2012-03-10 220 views
7

我有代碼等順序執行

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

有沒有在我的代碼任何差錯或這樣做的任何其他方式。 謝謝!

回答

13

正如你可能知道的,事情在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看看它提供的所有幫助函數,它非常有用!

+0

而不是迭代result.tasks我們可以迭代結果對象(JSON)嗎?我試過,但它給了我一個錯誤,如對象#沒有方法'foreach',也看到所有的異步幫助函數,但沒有對象迭代的函數。 – 2012-03-12 09:29:14

+0

您可以遍歷JSON中的數組...儘管您聽起來像是有一個對象,所以您無法迭代該對象。如果您在處理JSON對象時需要幫助,請發佈一個新問題。 – staackuser2 2012-03-12 14:07:20

+3

問題要求「在node.js中順序執行」。這完全相反。因此我投了票 – 2014-10-01 10:56:20

5

我剛剛創建(基於纖維)命名爲「wait.for」來稱呼在同步模式異步功能的簡單抽象:https://github.com/luciotato/waitfor

使用wait.for和異步代碼將是:

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