2015-10-12 2 views
41

Verwenden von Knoten 4.x. Wenn Sie eine Promise.all(promises).then() haben, was ist der richtige Weg, um die Daten zu lösen und an die nächste .then() weiterzugeben?Promise.all(). Dann() auflösen?

möchte ich so etwas wie dies zu tun:

Promise.all(promises).then(function(data){ 
    // Do something with the data here 
}).then(function(data){ 
    // Do more stuff here 
}); 

Aber ich bin nicht sicher, wie die Daten an den zweiten .then() zu bekommen. Ich kann resolve(...) nicht in der ersten verwenden. Ich fand heraus, ich kann dies tun:

return Promise.all(promises).then(function(data){ 
    // Do something with the data here 
    return data; 
}).then(function(data){ 
    // Do more stuff here 
}); 

Aber das scheint nicht, wie der richtige Weg, es zu tun ... Was ist der richtige Ansatz, um das?

Antwort

65

Aber das scheint nicht, wie der richtige Weg, es zu tun ..

Das ist in der Tat der richtige Weg, es (oder zumindest einen richtigen Weg, es zu tun) zu tun. Dies ist ein Schlüsselaspekt von Versprechen, sie sind eine Pipeline und die Daten können von den verschiedenen Handlern in der Pipeline massiert werden.

Beispiel:

const promises = [ 
 
    new Promise(resolve => setTimeout(resolve, 0, 1)), 
 
    new Promise(resolve => setTimeout(resolve, 0, 2)) 
 
]; 
 
Promise.all(promises) 
 
    .then(data => { 
 
    console.log("First handler", data); 
 
    return data.map(entry => entry * 10); 
 
    }) 
 
    .then(data => { 
 
    console.log("Second handler", data); 
 
    });

(. catch Handler der Kürze halber weggelassen In Produktionscode immer entweder das Versprechen verbreiten oder Ablehnung behandeln.)

Die Ausgabe, die wir sehen, ist:

 
First handler [1,2] 
Second handler [10,20] 

..., da die erste Behandlungsroutine, die Auflösung der beiden Versprechungen gets (1 und 2) als Array, und erzeugt dann ein neues Array mit jedem von jenen mit 10 multipliziert und gibt es zurück. Der zweite Handler erhält, was der erste Handler zurückgegeben hat.

Wenn die zusätzliche Arbeit Sie tun synchron ist, können Sie es auch in legte den ersten Handler:

Beispiel:

const promises = [ 
 
    new Promise(resolve => setTimeout(resolve, 0, 1)), 
 
    new Promise(resolve => setTimeout(resolve, 0, 2)) 
 
]; 
 
Promise.all(promises) 
 
    .then(data => { 
 
    console.log("Initial data", data); 
 
    data = data.map(entry => entry * 10); 
 
    console.log("Updated data", data); 
 
    return data; 
 
    });

... aber Wenn es asynchron ist, werden Sie dies nicht tun wollen, da es sich verschachtelt und die Verschachtelung schnell außer Kontrolle geraten kann.

+1

Interessant. Vielen Dank. Ist es also nicht möglich, einen Wert nach der anfänglichen 'Promise'-Funktion zu verwerfen? Oder wird ein Fehler irgendwo in der Kette zum '.catch()' führen? Wenn das der Fall ist, was ist der Sinn von "ablehnen" an erster Stelle? Warum nicht einfach Fehler werfen? Nochmals vielen Dank, –

+3

@JakeWilson: Das sind verschiedene Fragen. Aber du verwechselst zwei verschiedene Dinge: * Erstellen * und das Versprechen setzen und * das Versprechen * bearbeiten. Wenn Sie das Versprechen erstellen und festlegen, verwenden Sie "Auflösen" und "Ablehnen". Wenn Sie * bearbeiten *, wenn Ihre Verarbeitung fehlschlägt, werfen Sie tatsächlich eine Ausnahme, um den Fehlerpfad auszulösen.Und ja, Sie können auch eine Ausnahme vom ursprünglichen "Promise" -Rückruf auslösen (anstatt "reject" zu verwenden), aber nicht alle Fehler sind Ausnahmen. –

+0

Gut erklärt. Danke nochmal –