如何使用Firebase DB异步回调在嵌套循环中链接Q延迟的promise

时间:2017-10-12 01:08:15

标签: node.js firebase firebase-realtime-database q google-cloud-functions

注意:我知道已经有多个类似的已回答的问题,我已经阅读了,但我的情况仍然有问题。

我有一个(Google)Firebase云功能,它需要按特定顺序运行许多查询,也需要循环运行。例如这样的事情(使用LodashQ):

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必须等待,直到queryAqueryB(可以以任何顺序运行,因此Q.all())完成,并且functionD必须等到queryC完成。

思考上面的代码可以解决问题,但是当我运行云功能时,queryAqueryBqueryC和{{1都立即开始。

为我工作的唯一承诺是最终逻辑在最后运行一次, 等待functionD,{{1} }},queryAqueryB在开始之前我想要它 - 但最终函数内部的逻辑使用为queryC和{{1}中的每个functionD确定的信息无论如何它都无法正常工作。

有什么想法吗?谢谢:))

1 个答案:

答案 0 :(得分:2)

试试,你正在调用C和D:

myPromises.push(Q.all([queryA(),queryB()]).then(queryC).then(functionD));