我有像
这样的代码common.findOne('list', {'listId': parseInt(request.params. istId)}, function(err, result){
if(err) {
console.log(err);
}
else {
var tArr = new Array();
if(result.tasks) {
var tasks = result.tasks;
for(var i in tasks) {
console.log(tasks[i]);
common.findOne('tasks', {'taskId':parseInt(tasks[i])}, function(err,res){
tArr[i] = res;
console.log(res);
});
}
console.log(tArr);
}
return response.send(result);
}
});
它不是在node.js中按顺序执行的,所以我在执行结束时得到一个空数组。问题是它将首先执行console.log(tArr);
然后执行
common.findOne('tasks',{'taskId':parseInt(tasks[i])},function(err,res){
tArr[i] = res;
console.log(res);
});
我的代码或其他方式是否有任何错误。 谢谢!
答案 0 :(得分:14)
您可能已经意识到,事情在node.js中异步运行。因此,当您需要按特定顺序运行时,您需要使用控件库或基本上自己实现它。
我强烈建议您查看async,因为它很容易让您做到这样的事情:
var async = require('async');
// ..
if(result.tasks) {
async.forEach(result.tasks, processEachTask, afterAllTasks);
function processEachTask(task, callback) {
console.log(task);
common.findOne('tasks', {'taskId':parseInt(task)}, function(err,res) {
tArr.push(res); // NOTE: Assuming order does not matter here
console.log(res);
callback(err);
});
}
function afterAllTasks(err) {
console.log(tArr);
}
}
这里要看的主要内容是每个任务并行调用processEachTask,因此无法保证顺序。要标记已处理任务,您将在callback
的匿名函数中调用findOne
。这允许您在processEachTask
中执行更多异步工作,但仍然设法表示何时完成。完成每项任务后,它将调用afterAllTasks
。
看一下async来查看它提供的所有辅助函数,它非常有用!
答案 1 :(得分:6)
我最近创建了一个名为“ wait.for ”的简单抽象,以同步模式调用异步函数(基于光纤):https://github.com/luciotato/waitfor
使用wait.for和async你的代码将是:
var wait = require('waitfor');
...
//execute in a fiber
function handleRequest(request,response){
try{
...
var result = wait.for(common.findOne,'list',{'listId': parseInt(request.params.istId)});
var tArr = new Array();
if(result.tasks) {
var tasks = result.tasks;
for(var i in tasks){
console.log(tasks[i]);
var res=wait.for(common.findOne,'tasks',{'taskId':parseInt(tasks[i])});
tArr[i] = res;
console.log(res);
}
console.log(tArr);
return response.send(result);
};
....
}
catch(err){
// handle errors
return response.end(err.message);
}
};
// express framework
app.get('/posts', function(req, res) {
// handle request in a Fiber, keep node spinning
wait.launchFiber(handleRequest,req,res);
});