Hinweis: Ich weiß, es gibt mehrere ähnliche beantwortete Fragen da draußen bereits, ich lese sie, aber ich habe immer noch Schwierigkeiten mit meinem Szenario.So verketten Q verzögerte Versprechen in verschachtelten Schleife mit asynchronen Firebase DB Callbacks
Ich habe eine (Google) Firebase Cloud-Funktion, die viele Abfragen in einer bestimmten Reihenfolge auch in einer Schleife ausführen muss. So etwas wie dies zum Beispiel (unter Verwendung von Lodash und Q):
let users = [foo, bar, baz, qux, etc, ...];
let myPromises = [];
_.each(users, function (user) {
// Query A (async)
let queryA = function() {
let deferred = Q.defer();
let _queryA = function() {
admin.database().ref('blah').child(blah).once("value", function(snapshot) {
// logic
return deferred.resolve();
});
};
_queryA();
return deferred.promise;
};
// Query B (async)
let queryB = function() {
let deferred = Q.defer();
let _queryB = function() {
admin.database().ref('blah').child(blah).once("value", function(snapshot) {
// logic
return deferred.resolve();
});
};
_queryB();
return deferred.promise;
};
// Query C (async) with nested (async) query loop
let queryC = function() {
let deferred = Q.defer();
let _queryC = function() {
admin.database().ref('blah').child(blah).once("value", function(snapshot) {
// logic
let potatoPromises = [];
// another query loop
_.each(snapshot.val(), function (potato) {
let potato_deferred = Q.defer();
admin.database().ref('blah').child(potato.id).once("value", function(potato_snapshot) {
// logic
return potato_deferred.resolve();
});
potatoPromises.push(potato_deferred.promise);
});
Q.all(potatoPromises).then(function() { return deferred.resolve() });
});
};
_queryC();
return deferred.promise;
};
// Function D (sync)
let functionD() = function() {
let deferred = Q.defer();
let _functionD = function() {
// logic
});
_functionD();
return deferred.promise;
};
myPromises.push(Q.all([queryA(),queryB()]).then(queryC()).then(functionD()));
});
Q.all(myPromises).then(function() {
// Final logic ran only once after all promises in loop are resolved
});
Für jeden Benutzer wiederholt durch, queryC
müssen beide starten warten, bis queryA
und queryB
(die in beliebiger Reihenfolge ausgeführt werden kann, damit die Q.all()
) fertig sind, und functionD
müssen warten, bis queryC
fertig ist.
ich dachte den obigen Code würde den Trick tun, aber wenn ich die Wolke Funktion ausführen, queryA
, queryB
, queryC
und functionD
beginnen alle sofort.
Das einzige Versprechen, dass ist für mich arbeiten die letzte Logik ist einmal ganz am Ende lief, die ist warten queryA
, queryB
, queryC
und functionD
vor, wie ich beginnen möchte es to- aber die Logik innerhalb dieser letzten Funktion verwendet Informationen für jede user
in queryC
und functionD
bestimmt, so dass es sowieso nicht richtig funktioniert.
Irgendwelche Ideen? Thanks :)
'.then (queryC())' ruft sofort 'queryC' ... Sie wollen' .then (queryC) '.. usw. - Anmerkung: jedes '.then'-Argument sollte eine Funktion sein, nicht das Ergebnis des Aufrufs einer Funktion - (natürlich, wenn die aufgerufene Funktion eine Funktion liefert, die ganz in Ordnung ist, aber Ihre Funktionen keine Funktion zurückgeben) –
in Zusammenfassung - myPromises.push (Q.all ([queryA(), queryB()]). dann (queryC) .then (functionD)) 'ist näher an dem, was Sie beabsichtigt haben - obwohl ich sicher bin, dass der Code sehr groß sein kann vereinfacht, da ich mir sicher bin, dass Firebase-Methoden sowieso schon ein Promise zurückgeben –
Okay, ich werde das jetzt ausprobieren. Was die Firebase-Abfrage verspricht, denke ich, dass Sie Recht haben. Ich lese gerade jetzt https://firebase.googleblog.com/2016/01/keeping-our-promises-and-callbacks_76.html und es zeigt, wie ich sie verwenden kann. – WillB