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

How to chain Q deferred promises in nested loop with Firebase DB async callbacks

注意:我知道已经有多个相似 已回答的问题,我阅读了它们,但我的场景仍然有困难。

我有一个 (Google) Firebase Cloud Function,它需要 运行 许多查询,按特定顺序,也在循环中。例如这样的事情(使用 Lodash and 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 必须等到 queryAqueryB(可以按任何顺序 运行,因此 Q.all()) 完成,functionD 必须等到 queryC 完成。

认为上面的代码可以解决问题,但是当我运行云函数时,queryAqueryBqueryCfunctionD都马上开始了。

为我工作的唯一承诺是最后的逻辑运行,在像我希望的那样开始之前等待 queryAqueryBqueryCfunctionD,但最终函数内部的逻辑使用为每个 [=25] 确定的信息=] 在 queryCfunctionD 中,所以无论如何它都不能正常工作。

有什么想法吗?谢谢:)

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

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