如何从异步函数

时间:2015-11-01 14:58:16

标签: node.js asynchronous

我正在寻找答案并找到this。就像在jquery中一样,有when函数。使用一些指导来同步我的异步调用我在Node中使用async.js 这是代码。

async.forEach(dateInDateFormat, function(item, callback) {
        console.log(moment(item.startDate).toDate());
        var result = Trip.aggregate([{
            "$unwind": "$trips"
        }, {
            "$match": {
                "trips.startTime": {
                    "$gte": moment(item.startDate).toDate(),
                    "$lte": moment(item.endDate).toDate()
                }
            }
        }, {
            "$group": {
                "_id": {
                    "date": {
                        "$dayOfMonth": "$trips.startTime"
                    }
                },
                "distance": {
                    "$sum": "$trips.distance"
                }
            }
        }]);
        result.exec(function(err, doc) {
            console.log(doc);
        });
        console.log("Executing callback");
        callback();
    }, function(error) {
        console.log("Loop over");
    });

这是输出。

Executing callback
Loop over
[ { _id: { date: 23 }, distance: 0 },
{ _id: { date: 22 }, distance: 0 },
{ _id: { date: 21 }, distance: 0 } ]
[ { _id: { date: 29 }, distance: 210 },
  { _id: { date: 27 }, distance: 210 },
  { _id: { date: 26 }, distance: 210 },
  { _id: { date: 25 }, distance: 0 } ]
[]

如你所见。在获取数据之前执行回调和循环执行。我无法使用res.send()将其发回给我的Angular前端。 一个答案是您无法从异步函数返回值。您只返回一个回调。在这种情况下我该怎么做? 要么 我如何使用async.series([])功能。因为我也使用了它,甚至没有给我确切的结果。 感谢

修改的 总之,回答函数的位置很重要。如果你把它放在错误的地方,不要期望写答案。请参阅答案和评论主题中的代码以获得更好的解释。

1 个答案:

答案 0 :(得分:2)

callback有点神奇,只是向async.foreach表明特定foreach执行已完成。我不熟悉aggregate函数或exec,所以我假设聚合构建了一个查询,而exec正在异步执行该查询。

forEach回调可以移动到result.exec结果。这将向async表明该特定查询的执行已结束。当所有执行结束时,传递的函数将执行到forEach的第二个参数。执行时,所有功能都已完成或发生错误,在这种情况下,您可以sendres

整体流程:

  1. 创建要异步操作的数据列表
  2. 异步执行列表中每个项目的函数(async.forEach的第二个参数)。
    1. 构建聚合查询
    2. 异步执行聚合查询
    3. 通过调用async.foreach函数
    4. callback表示已完成集合操作
  3. 当为数组中的每个项目调用callback时,异步将调用作为第3个参数传递给async.forEach的函数。
  4. 将结果返回给客户,因为所有任务都已解决。
  5. async.forEach(dateInDateFormat, function(item, callback) {
            console.log(moment(item.startDate).toDate());
            var result = Trip.aggregate([{
                "$unwind": "$trips"
            }, {
                "$match": {
                    "trips.startTime": {
                        "$gte": moment(item.startDate).toDate(),
                        "$lte": moment(item.endDate).toDate()
                    }
                }
            }, {
                "$group": {
                    "_id": {
                        "date": {
                            "$dayOfMonth": "$trips.startTime"
                        }
                    },
                    "distance": {
                        "$sum": "$trips.distance"
                    }
                }
            }]);
            result.exec(function(err, doc) {
                console.log(doc);
                console.log("Executing callback");
                callback();
            });
        }, function(error) {
            // all tasks passed to forEach have been completed, or 
            // an error has occurred
            res.send('COMPLETE');
            console.log("Loop over");
        });
    

    对我来说,一个简单的操作如何拥有如此疯狂的编程流程真是太疯狂了:)