node.js中的顺序执行

pri*_*tel 8 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); 
  }
});
Run Code Online (Sandbox Code Playgroud)

它不是在node.js中按顺序执行的,所以我在执行结束时得到一个空数组.问题是它将首先执行console.log(tArr);然后执行

common.findOne('tasks',{'taskId':parseInt(tasks[i])},function(err,res){
      tArr[i]  = res;       
      console.log(res);                                         
});                       
Run Code Online (Sandbox Code Playgroud)

我的代码或任何其他方式是否有任何错误.谢谢!

sta*_*er2 15

您可能已经意识到,事情在node.js中异步运行.因此,当您需要按某种顺序运行时,您需要使用控件库或基本上自己实现它.

我强烈建议你看看异步,因为它很容易让你做这样的事情:

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

这里要看的主要内容是processEachTask与每个任务并行调用,因此无法保证顺序.要标记任务已处理,您将调用callback匿名函数findOne.这允许您执行更多异步工作,processEachTask但仍然设法表示何时完成.当每个任务完成后,它将会调用afterAllTasks.

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

  • 该问题要求"在node.js中顺序执行".这恰恰相反.因此,我的投票 (3认同)

Luc*_*ato 6

我最近创建了一个名为" wait.for " 的简单抽象来在同步模式下调用异步函数(基于Fibers):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);
    });
Run Code Online (Sandbox Code Playgroud)