Javascript Node.js:forEach inside async.series
我开始为工作开发node.js应用程序,但我不能“异步思考”。 在我的函数中,我必须执行一个查询,对于每一行,我必须执行另一个查询来计算最终结果并创建json。 我尝试这样做:Javascript Node.js:forEach inside async.series,javascript,json,node.js,asynchronous,foreach,Javascript,Json,Node.js,Asynchronous,Foreach,我开始为工作开发node.js应用程序,但我不能“异步思考”。 在我的函数中,我必须执行一个查询,对于每一行,我必须执行另一个查询来计算最终结果并创建json。 我尝试这样做: async.series([ function(callback) { db.myCannedResponseList(req.params.websiteid, function(err,questions) { if (err) return callb
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);
});
但是有一个问题:getCannedAnswer的结果显示在res.json(输出)之后。
如何解决此问题?完成
forEachSeries
后,需要调用回调。您还需要调用传递给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
异步函数是嵌套的,因此需要作为回调函数 以下是一种方法:
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);
});
我不确定这个函数应该做什么,但是如果您在async.series
中遇到错误,您应该调用res.json(500,error)
或者在成功时不调用res
一个好的方法是将这个函数完全分离,并让它在完成后调用另一个回调。然后在那里调用res
此外,您可以传递对象,而不是将数组传递给async.series
,这样结果将被命名为命名空间
完整示例:
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);
}
然后从另一个模块调用函数:
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)
});
您应该决定是要在内部还是外部控制错误
getCannedStuff
,但传递错误是一种很好的方法,而不是一直执行if(err)
,以查看是否发生错误。可以只传递回调
,而不是匿名函数(err)
。它将抛出on返回next(err)
因为next
无论如何都不存在(除非它是在给定代码段之外定义的)。如果在最终回调中出现错误,调用next(err)
对于定义了应用程序范围错误处理程序的Express应用程序来说是非常标准的行为。@robertklep True。我只是想用这个例子来说明我的观点