注意:我知道已经有多个类似的已回答的问题,我已经阅读了,但我的情况仍然有问题。
我有一个(Google)Firebase云功能,它需要按特定顺序运行许多查询,也需要循环运行。例如这样的事情(使用Lodash和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
});
对于每个迭代过的用户,queryC
必须等待,直到queryA
和queryB
(可以以任何顺序运行,因此Q.all()
)完成,并且functionD
必须等到queryC
完成。
我思考上面的代码可以解决问题,但是当我运行云功能时,queryA
,queryB
,queryC
和{{1都立即开始。
为我工作的唯一承诺是最终逻辑在最后运行一次, 等待functionD
,{{1} }},queryA
和queryB
在开始之前我想要它 - 但最终函数内部的逻辑使用为queryC
和{{1}中的每个functionD
确定的信息无论如何它都无法正常工作。
有什么想法吗?谢谢:))
答案 0 :(得分:2)
试试,你正在调用C和D:
myPromises.push(Q.all([queryA(),queryB()]).then(queryC).then(functionD));