【发布时间】:2017-10-12 11:35:19
【问题描述】:
注意:我知道已经有多个类似已回答的问题,我阅读了它们,但我的方案仍然有困难。
我有一个 (Google) Firebase Cloud Function,它需要以一定的顺序运行许多查询,也需要循环运行。例如这样的事情(使用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 必须等到@ 987654330@已完结。
我认为上面的代码可以解决问题,但是当我运行云函数时,queryA、queryB、queryC 和 functionD 都立即启动。
正在为我工作的唯一 Promise 是最后运行一次的最终逻辑,正在等待queryA、queryB、@987654337 @ 和 functionD 在开始之前像我想要的那样 - 但最终函数内部的逻辑使用为 queryC 和 functionD 中的每个 user 确定的信息,所以它无论如何都不能正常工作。
有什么想法吗?谢谢:)
【问题讨论】:
-
.then(queryC())立即调用queryC... 你想要.then(queryC)... 等等 - 注意:任何.then参数应该是一个函数,而不是调用函数的结果 - (当然如果被调用的函数返回一个很好的函数,但是你的函数不返回一个函数) -
总而言之 - myPromises.push(Q.all([queryA(),queryB()]).then(queryC).then(functionD))` 更接近您的预期 - 不过,我确信代码可以大大简化,因为我确信
firebase方法已经返回了一个 Promise 反正 -
快速且未经测试(显然)重写 - jsfiddle.net/h5r9v0b9
-
我在您的代码中注意到的一件事 ...
let queryA = () {...这不是有效的 javascript - 所有这些代码都应该是let queryA = () => {或let queryA = function() {吗? -
一切都好,我猜到你的意思了
标签: node.js firebase firebase-realtime-database q google-cloud-functions