如何在 sails js 中获取所有函数异步的结果

How to get result of all function asynchronous in sails js

我想根据请求中作为数组传递的条件执行 n 次查询。我可以依次执行所有查询,但有时第二个查询会在第一个查询之前执行,因此只显示第二个查询的结果。

这就是我到现在所做的。

var where_clauses = condition_array;
return new Promise(function (resolve, reject) {
    var counter = [];
    async.series([
        function (counterCB) {
            where_clauses.forEach(function (where_clause, i) {
                Model.count(where_clause, function (err, result) {
                    if (err) {
                        return counterCB(err);
                    }
                    console.log('result', result);
                    counter.push(result);
                    if ((where_clauses.length - 1) === i) {
                        return counterCB(null, counter);
                    }
                });
            });
        }
    ], function (err, result) {
        console.log('counter', counter);
        return err ? reject(err) : resolve(counter);
    });
});

下面是这个的输出。

输出 1:

result 26627
result 37630
counter [ 26627, 37630 ] // This is return array

输出 2:

result 37630
counter [ 37630 ] // This is return array
result 26627

现在我希望所有查询的结果都存储在数组中,而不是在我需要 return 之后。谁能帮帮我?

快速解决方案就是更改设置结束条件的方式。由于您的异步回调可能会以任何顺序执行,因此您不应在 "last" 回调之后结束,而应在获得预期结果数之后结束。

尝试改变这个:

if ((where_clauses.length - 1) === i) {
    return counterCB(null, counter);
}

对此:

if (counter.length >= where_clauses.length) {
    return counterCB(null, counter);
}

但是,每次要等待多个查询完成时都进行设置很困难,值得使用其中一个库来简化它。我使用 Q。然后当我想等待多个查询时,它看起来像这样:

var Q = require('q');

module.exports = {

    getLotsOfData: function(req, res) {
        Q.all([
            User.find({flagged: true}),
            Group.find({flagged: true}),
            someOtherCustomPromise(args)
        ]).spread(function(users, groups, otherpromiseresult) {
            // do whatever you want with all three result sets
            return res.send({
                users: users,
                groups: groups,
                otherResult: otherpromiseresult
            });
        }).fail(function(err) {
            // handle the error
        });
    },
    // etc

}

我主要是这样做的 - 一次启动多个查询,然后 运行 在我获得所有结果后编写一些代码...但是 Q 还有很多其他实用方法。

希望对您有所帮助!


更新

如果您需要可变数量的异步调用,您可以通过将一个承诺数组传递给 Q 然后使用传播回调中的 arguments 关键字访问结果来处理它:

Q.all(arrayOfPromises).spread(function() {
    var results = [];
    for (var i = 0; i < arguments.length; i++) {
        var oneResult = arguments[i];
        // oneResult is the result of the i'th promise in arrayOfPromises
        results[i] = oneResult;
    }
    return res.sent(results);
}).fail(function(err) {
    // handle the error
});