2017-12-22 7 views
0

Ich habe eine API, die nach dem vom Benutzer bereitgestellten Begriff sucht, gibt ein Array mit Ergebnissen zurück, löst dann asynchrone Anforderungen für jedes der Ergebnisse aus und erhält Ergebnisse für jeden dieser zweiten Stapel von Anforderungen . Ich möchte, dass die API den Fortschritt, nicht nur das Endergebnis, berichtet. Also, wenn ich die folgende Anfrage mache, sollte ich Updates wie folgt erhalten:nodejs async/erwarten verschachtelten API-Fortschritt

Der meiste relevante Code wird unten gezeigt. Fwiw, ich benutze hapijs für meine Anwendung.

let imagesOfRecords = {}; 

const getImages = async function (q) { 

    console.log(`searching for ${q}…`); 
    const uri = `http://remoteserver/?q=${q}`; 
    const {res, payload} = await Wreck.get(uri); 
    const result = JSON.parse(payload.toString()).hits; 
    const numOfFoundRecords = result.total; 

    if (result.total) { 

     console.log(`found ${result.total}… now getting images…`); 
     const foundRecords = result.hits.map(getBuckets); 
     Promise.all(foundRecords).then(function() { 

      console.log(`found ${Object.keys(imagesOfRecords).length} images… done`); 
      reply(imagesOfRecords).headers = res.headers; 
     }).catch(error => { 
      console.log(error) 
     }); 
    } 
    else { 
     console.log('nothing found'); 
     reply(0).headers = res.headers; 
    } 
}; 

const getBuckets = async function(record) { 

    const { res, payload } = await Wreck.get(record.links.self); 
    const bucket = JSON.parse(payload.toString()).links.bucket; 
    await getImageFiles(bucket, record.links.self); 
}; 

const getImageFiles = async function(uri, record) { 

    const { res, payload } = await Wreck.get(uri); 
    const contents = JSON.parse(payload.toString()).contents; 
    imagesOfRecords[record] = contents.map(function(el) { 
     return el.links.self; 
    }); 
}; 

Sobald ich das umsetzen kann, wäre meine nächste Aufgabe, diese progressive Update in einer Web-Anwendung zu implementieren, die den oben genannten API verwendet.

Antwort

1

Um Ergebnisse mit jedem Schritt Ihrer Backend-Anforderung anzuzeigen, können Sie EventEmitter verwenden, der bei jedem Fortschrittsschritt ein Ereignis ausgibt. Sie können über Ereignisse here lesen.
Einfache Implementierung:

const events = require('events'); 
const eventEmitter = new events.EventEmitter(); 

//your request code 
Promise.all(foundRecords).then(function() { 
    console.log(`found ${Object.keys(imagesOfRecords).length} images… done`); 
    eventEmitter.emit('progress'); 
    reply(imagesOfRecords).headers = res.headers; 
}) 

const eventReaction = (e) => { 
    // do something with event, console log for example. 
} 
eventEmitter.on('progress', eventReaction); 

Weitere Beispiele, die Sie here und here finden.
Um Ereignisse zum Client anzuzeigen, können Sie die Bibliothek socket.io verwenden. Ich denke, Sie können ziemlich einfache Erklärungen finden, wie socket.io in documentation funktioniert.
Wenn Sie Ereignisse zwischen Servern oder Prozessen senden möchten und etwas weiter gehen möchten, können Sie mehr über 0MQ (null mq) lesen und es ist Knoten implementation

+0

das ist großartig, danke. Ich werde die Vorschläge ausprobieren. Obwohl mir jetzt etwas sagt, dass dies mehr Mühe als wert sein könnte, da ich auch dem Konsumenten meiner API eine Möglichkeit geben müsste, zwischen einer Fortschrittsaktualisierung und dem Ergebnis zu unterscheiden. Es gibt viel zu experimentieren. – punkish

Verwandte Themen