2016-05-06 5 views
2

Dies ist mein erster Schuss auf verschachtelte Versprechen. Ich benutze die bluebird Bibliothek, aber ich denke, die Idee ist die gleiche für alle Versprechen Bibliotheken.Lösen einer Reihe von Versprechen aus einem Elternversprechen

Auf einem hohen Niveau, ist es das, was ich versuche zu tun:

myService.getSomeData(url) 
.then((data) => { 
    myOtherService.getMoreData(data.uniqueId) 
    .then((thisDataIsAnArray) => { 
     //loop over the data above and do something 
    }); 
}); 

getMoreData() soll X Service-Anrufe und die Ergebnisse in einem Array X Elemente lang. Hier fange ich an, mich zu verirren, da ich mir nicht sicher bin, wie ich diese Methode herstellen soll und was ich davon zurückkriege. Ich habe ein paar Stiche bei Bluebirds Promise.all und Promise.map genommen, aber ich zappele und dachte, ich würde Vorschläge erbitten.

+0

Versuchen, Ihr Ziel zu verstehen. Also, Sie wollen eine Reihe von Versprechen ausführen, dann eine weitere Reihe von Versprechen angesichts der Beschlüsse aus der ersten Reihe von Versprechen, dann führen Sie eine dritte Reihe von Logik auf der Grundlage der Beschlüsse aus der zweiten Reihe von Versprechen? Eines der Ziele von Versprechen ist es, "Callback-Hölle" zu entfernen. Folglich könnte es für Sie angenehm sein, Versprechen zu verketten, anstatt sie zu verschachteln. – jpodwys

+3

Sie könnten mit [flattening Ihre Kette] beginnen (http://stackoverflow.com/a/22000931/1048572). – Bergi

+1

Jede asynchrone Methode sollte ein Versprechen * für das Ergebnis der asynchronen Aktionen in ihr zurückgeben. Jeder einzelne. – Bergi

Antwort

3

Return all the promises!

Promises sind nur Rückgabewerte Sie Rückrufe, statt vorbei Rückrufe in Funktionen befestigen. Wenn Sie nicht alle zurückgeben, können die Callbacks nicht ketten oder alle ihre Fehler erfassen.

Auch Rückkehr von allen .then 's sofort haben Sie ein anderes Versprechen. Das macht die Dinge flacher.

2

Versprechung Iteration verdrehte völlig mein Gehirn das erste Mal, das ich es auch versuchte. Ich denke, die Dokumentation von Bluebird macht einen ziemlich schlechten Job, der die üblichen Anwendungsfälle unterscheidet, aber ich werde nicht weiter darauf eingehen, weil (a) ich Bluebird liebe und (b) ich keine Zeit habe, die Dokumente zu aktualisieren.

Ich fühle mich wie Promise.map ist das Richtige für Ihr Szenario.

myService.getSomeData(url) 
    .then((data) => 
    { 
     return myOtherService.getMoreData(data.uniqueId) 
    }) 
    .map((item) => 
    { 
     return doSomethingWithData(item); 
    }) 
    .then((results) => 
    { 
     // do something with the result array. 
    }); 

Je nachdem, was Sie mit den Ergebnissen tun wollen, wo ich verwendet habe, .map Sie auch .reduce verwenden oder .each. Beachten Sie, dass .each den Rückgabewert des Versprechens, mit dem es verkettet ist, nicht ändert, daher der Kommentar "nur für Nebenwirkungen verwenden" in den Bluebird-Dokumenten.

Der Unterschied zwischen der Instanz und statischen Methoden ist natürlich, dass mit statischen müssen Sie das Array z. Promise.map(array, (item) => {}).

Auch, wie @jib sagte - immer einen Wert innerhalb Ihrer Rückrufe zurückgeben. Dies wird dir viele Schmerzen auf der ganzen Linie ersparen.

+0

Danke für das Beispiel. Es scheint, dass 'doSomethingWithData()' eine Verheißung im Beispiel zurückgeben muss - was ist wenn nicht und gibt nur die Zahl 2 zurück? Sollte ich den Anruf in "Promise.promistify" oder etwas in dieser Richtung einpacken? – jkj2000

+0

@ jkj2000 Wenn 'doSomethingWithData (item)' async ist, sollten Sie ein Versprechen zurückgeben. Wenn die Signatur wirklich 'doSomethingWithData (item, callback)' 'ist, dann ist' Promise.promisify' eine gute Idee, oder wenn es bereits implementiert wurde, dann sollte man von Anfang an nur eine auf Versprechen basierende Implementierung in Betracht ziehen. Im Allgemeinen, nein, Sie müssen kein Versprechen zurückgeben, jeder Wert ist in Ordnung, auch Mischungen von Versprechen und nicht versprechen Werte. –

Verwandte Themen