2012-03-10 14 views
7

私は実行の終了時に空の配列を取得するので、それは、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); 
    } 
}); 

ようなコードを有しています。問題は、それが最初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

iterate over result.tasks結果オブジェクト(JSON)を反復処理できますか?私は試してみましたが、Object#のようなエラーが発生しました。 'foreach'メソッドがなく、非同期のヘルパー関数もすべて表示されますが、オブジェクト反復の関数はありません。 –

+0

JSONにある配列を反復処理することはできますが、Objectを持っているかのように聞こえるので、繰り返し処理することはできません。 JSONオブジェクトの処理に関する助けが必要な場合は、新しい質問を投稿してください。 – staackuser2

+3

"node.jsの順次実行"について質問します。これは正反対です。したがって私の下の投票 –

5

私は最近、(繊維に基づいて)同期モードで非同期関数を呼び出すために「wait.for」という名前のシンプルな抽象作成しました:wait.forを使用してhttps://github.com/luciotato/waitfor

をし、非同期あなたのコードは次のようになります。

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); 
    }); 
関連する問題