简体   繁体   English

Node.js:async.series内部的forEach

[英]Node.js: forEach inside async.series

I started developing my node.js app for work but i can't "think asynchronous". 我开始开发工作的node.js应用程序,但是我无法“认为异步”。 In my function i have to do a query and for every rows i have to do another query to compute the final result and create my json. 在我的函数中,我必须执行一个查询,对于每一行,我都必须执行另一个查询以计算最终结果并创建我的json。 I try to do this: 我尝试这样做:

async.series([
    function(callback) {
            db.myCannedResponseList(req.params.websiteid, function(err,questions) {
                if (err) return callback(err);
                ...
                callback();
            });
        },
    function(callback) {
            async.forEachSeries(temp,function(quest,callback) {
                    db.getCannedAnswer(quest.id, function(err,answers) {
                         console.log(answers);
                    });
            }, function(err) {
                if (err) return next(err);
            });
            callback();
        }
    ],
        function(err) { 
            if (err) return next(err);
            res.json(output);
    });

But there is a problem: the result of getCannedAnswer is show after res.json(output) . 但是有一个问题: getCannedAnswer的结果在res.json(output)之后显示。 How can i solve it? 我该如何解决?

You need to call the callback when the forEachSeries is done. forEachSeries完成后,您需要调用回调。 You also need to call the callback that is passed to the forEachSeries handler functions: 您还需要调用传递给forEachSeries处理函数的回调:

async.forEachSeries(temp, function(quest, callback2) {
  db.getCannedAnswer(quest.id, function(err, answers) {
    console.log(answers);
    // call the callback for forEachSeries so it can proceed:
    callback2(); 
  });
}, callback); // forEachSeries is done here, call the callback for async.series

Your async functions are nested and so need to be your callbacks. 您的异步函数是嵌套的,因此需要作为您的回调。

Here's an approach: 这是一种方法:

    async.series([
        //async.apply(db.myCannedResponseList,req.params.websiteid), // This is equivalent to the first function below
        //db.myCannedResponseList(req.params.websiteid,callback), // This is equivalent too
        function(callback) {
            db.myCannedResponseList(req.params.websiteid, callback);
        },    
        function(callback) {
            // I'm not sure forEach is the best choice here
            // since it's callback isn't called with all the results so it won't be able to be forwarded...
            // Personally, I use async.times for something like this.
            async.times(temp.length,function(i,next) {
                db.getCannedAnswer(temp[i].id,next);
            },callback)
        }
     ],function(err) { 
          if (err) return next(err);
          res.json(output);
    });

I'm not sure what this function should do but if you encounter an error in async.series you should either call res.json(500,error) or not call res on success. 我不确定该函数应该做什么,但是如果您在async.series遇到错误, async.series应该调用res.json(500,error)或成功时不调用res

A good approach would be to separete this function altogether and have it call another callback when it's done. 一个好的方法是完全分离此函数,并在完成后调用另一个回调。 You would then call res there. 然后,您将在那里呼叫res

Also, instead of passing an array to async.series you can pass an object so the results will be namespaced. 另外,可以将对象传递给名称空间,而不是将数组传递给async.series

Full example: 完整示例:

    function getCannedStuff(data,callback){
        async.series({
            list : async.apply(db.myCannedResponseList,data.websiteid),
            answer : function(cb) {
                async.times(data.temp.length,function(i,next) {
                db.getCannedAnswer(data.temp[i].id,next);
                },cb)
            }
        },callback);  
    }

Then call the function from another module: 然后从另一个模块调用该函数:

    getCannedStuff({
        websiteid: req.params.websiteid,
        temp:temp
    },function(error,results) {
        console.log(results.list);
        console.log(results.answer);
        if(err) return res.json(500,{error : error});
        res.json(results)
    });

You should decide if you want to control the error inside or outside getCannedStuff but it's a good approach to pass them along and not do all the time if(err) to see if they occur. 您应该决定是要控制getCannedStuff内部还是外部的错误,但这是一种传递错误的好方法,而不是一直执行if(err)来查看它们是否发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM