【问题标题】:Sequential execution in node.jsnode.js 中的顺序执行
【发布时间】:2014-06-17 04:08:40
【问题描述】:

我有类似的代码

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


    【解决方案1】:

    您可能知道,在 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 与每个任务并行调用,因此不能保证顺序。为了标记该任务已被处理,您将在来自findOne 的匿名函数中调用callback。这使您可以在processEachTask 中进行更多异步工作,但仍设法表示何时完成。当每个任务完成后,它会调用afterAllTasks

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

    【讨论】:

    • 我们可以迭代结果对象(JSON),而不是遍历 result.tasks 吗?我试过了,但它给了我一个错误,比如 Object # has no method 'foreach' 并且还看到了 async 的所有辅助函数,但没有用于对象迭代的函数。
    • 您可以遍历 JSON 中的数组...不过听起来您有一个对象,所以您不能遍历它。如果您在处理 JSON 对象方面需要帮助,请发布一个新问题。
    • 问题要求“node.js 中的顺序执行”。这恰恰相反。因此我的反对票
    【解决方案2】:

    我最近创建了一个名为“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);
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-05-07
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 2017-08-30
      • 2017-01-13
      • 1970-01-01
      • 2012-06-29
      相关资源
      最近更新 更多