node.js 中的顺序执行
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9644197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Sequential execution in node.js
提问by priyanka patel
I have code like
我有类似的代码
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);
}
});
It is not executed sequentially in node.js so I get an empty array at the end of execution. Problem is it will first execute console.log(tArr);and then execute
它不是在 node.js 中按顺序执行的,所以我在执行结束时得到一个空数组。问题是它会先执行console.log(tArr);然后执行
common.findOne('tasks',{'taskId':parseInt(tasks[i])},function(err,res){
tArr[i] = res;
console.log(res);
});
Is there any mistake in my code or any other way for doing this. Thanks!
我的代码或任何其他方式是否有任何错误。谢谢!
回答by staackuser2
As you are probably aware, things run asynchronously in node.js. So when you need to get things to run in a certain order you need to make use of a control library or basically implement it yourself.
您可能知道,在 node.js 中异步运行。因此,当您需要按特定顺序运行时,您需要使用控制库或基本上自己实现。
I highly suggest you take a look at async, as it will easily allow you to do something like this:
我强烈建议您查看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);
}
}
The main things to see here is that processEachTask gets called with each task, in parallel, so the order is not guaranteed. To mark that the task has been processed, you will call callbackin the anonymous function from findOne. This allows you to do more async work in processEachTaskbut still manage to signify when it is done. When every task is done, it will then call afterAllTasks.
这里要看到的主要事情是 processEachTask 与每个任务并行调用,因此不能保证顺序。为了标记任务已被处理,您将从中调用callback匿名函数findOne。这允许你做更多的异步工作,processEachTask但仍然设法在完成时表示。当每个任务完成后,它会调用afterAllTasks.
Take a look at asyncto see all the helper functions that it provides, it is very useful!
看看async看看它提供的所有辅助函数,它非常有用!
回答by Lucio M. Tato
I've recently created a simple abstraction named "wait.for" to call async functions in sync mode (based on Fibers): https://github.com/luciotato/waitfor
我最近创建了一个名为“ wait.for”的简单抽象,以在同步模式下调用异步函数(基于 Fibers):https: //github.com/luciotato/waitfor
Using wait.for and async your code will be:
使用 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);
});

