在node.js中顺序执行

我有类似的代码

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); }); 

在我的代码中是否有任何错误或者其他方式来执行此操作。 谢谢!

正如你可能知道的,事情在node.js中asynchronous运行。 所以当你需要按照一定的顺序运行时,你需要使用一个控制库或者自己实现。

我强烈build议你看看asynchronous ,因为它会轻松地让你做这样的事情:

 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与每个任务并行调用,所以顺序不能保证。 为了标记任务已经被处理,你将在findOne的匿名函数中调用callback函数。 这使您可以在processEachTask执行更多的asynchronous工作,但仍可以在完成时进行表示。 当每个任务完成后,它将在完成任务后调用。

看看async ,看看它提供的所有帮助函数,这是非常有用的!

我最近创build了一个名为“ wait.for ”的简单抽象,以同步模式调用asynchronous函数(基于Fibers): https : //github.com/luciotato/waitfor

使用wait.for和asynchronous你的代码将是:

 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); });