Richtiger Weg, Schleifen für Versprechen zu schreiben.
Wie ordnungsgemäß zu erstellen eine Schleife, um sicherzustellen, dass die folgenden Versprechen nennen und die verkettete logger.log(res) läuft synchron durch iteration? (bluebird)
db.getUser(email).then(function(res) { logger.log(res); }); //this is a promise
Habe ich versucht, das auf folgende Weise (Methode von http://blog.victorquinn.com/javascript-promise-while-loop )
var Promise = require('bluebird');
var promiseWhile = function(condition, action) {
var resolver = Promise.defer();
var loop = function() {
if (!condition()) return resolver.resolve();
return Promise.cast(action())
.then(loop)
.catch(resolver.reject);
};
process.nextTick(loop);
return resolver.promise;
});
var count = 0;
promiseWhile(function() {
return count < 10;
}, function() {
return new Promise(function(resolve, reject) {
db.getUser(email)
.then(function(res) {
logger.log(res);
count++;
resolve();
});
});
}).then(function() {
console.log('all done');
});
Obwohl es scheint zu funktionieren, aber ich glaube nicht, dass es garantiert, dass die Reihenfolge der Berufung logger.log(res);
Irgendwelche Vorschläge?
InformationsquelleAutor der Frage user2127480 | 2014-07-09
Du musst angemeldet sein, um einen Kommentar abzugeben.
Tatsächlich, es funktioniert. Die Anweisung wird ausgeführt bevor die
resolve
nennen.Viele. Das wichtigste ist, Ihre Nutzung der erstellen-Versprechen-manuell antipattern - tun Sie einfach nur
Zweitens, dass
while
Funktion vereinfacht werden könnte, eine Menge:Dritten, würde ich nicht verwenden, eine
while
- Schleife (mit einer closure-variable) sondern einefor
Schleife:InformationsquelleAutor der Antwort Bergi
Wenn Sie wirklich wollen, eine Allgemeine
promiseWhen()
Funktion für diese und andere Zwecke, dann mit allen Mitteln tun, mit Bergi ist Vereinfachungen. Jedoch, wegen der Art, verspricht Arbeit, vorbei Rückrufe auf diese Weise ist in der Regel unnötig und zwingt Sie, um zu springen über komplexe wenig Reifen.Soweit ich sagen kann, Sie versuchen :
.then()
Kette über Rekursion.Definiert also, das problem ist eigentlich das ein, diskutiert Sie unter "Die Sammlung Kerfuffle" in Versprechen Anti-patternsdie zwei einfache Lösungen :
Array.prototype.map()
Array.prototype.reduce()
.Den parallelen Ansatz (einfach) das Problem, dass Sie versuchen zu vermeiden, dass die Reihenfolge der Antworten ist ungewiss. Der serielle Ansatz erstellen Sie die benötigte
.then()
Kette - flat - keine Rekursion.Rufen Sie wie folgt vor :
Wie Sie sehen können, gibt es keine Notwendigkeit für das hässliche äußere var
count
oder es ist verbundencondition
Funktion. Die Grenze (von 10 in der Frage) ist bestimmt nicht ganz von der Länge des ArraysarrayOfEmailAddys
.InformationsquelleAutor der Antwort Roamer-1888
Hier ist, wie ich es mit den standard-Promise-Objekt.
InformationsquelleAutor der Antwort youngwerth
Gegeben
Erforderlich
Lösung
InformationsquelleAutor der Antwort kamran
Bergischen empfohlene Funktion ist wirklich nett:
Ich möchte immer noch eine kleine Ergänzung, die Sinn macht, bei der Verwendung verspricht:
Diese Weise wird die while-Schleife eingebettet werden kann in ein Versprechen Kette und löst sich mit lastValue (auch wenn die action() wird nie ausgeführt). Siehe Beispiel:
InformationsquelleAutor der Antwort Patrick Wieth
Ich würde so etwas wie dieses:
in dieser Weise, dataAll ist eine sortierte array von element zu melden. Und log-Vorgang durchzuführen, wenn alle Versprechungen werden gemacht.
InformationsquelleAutor der Antwort Claudio M
Es ist ein neuer Weg, um dieses Problem zu lösen und es durch die Verwendung von async/await.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
https://ponyfoo.com/articles/understanding-javascript-async-await
InformationsquelleAutor der Antwort tomasgvivo
InformationsquelleAutor der Antwort Tengiz
Wie über diese eine, mit BlueBird?
InformationsquelleAutor der Antwort wayofthefuture
Hier ist eine andere Methode (ES6 w/std Versprechen). Verwendet lodash, unterstreichen, geben Sie exit Kriterien (return === false). Beachten Sie, dass Sie könnte leicht fügen Sie eine exitIf () - Methode in den Optionen zum ausführen in doOne().
InformationsquelleAutor der Antwort Gary Skiba