2012-03-10 28 views
7

tôi có mã nhưthực hiện tuần tự trong 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); 
    } 
}); 

Nó không phải được thực hiện tuần tự trong Node.js vì vậy tôi có được một mảng trống ở cuối thực hiện. Vấn đề là trước tiên nó sẽ thực hiện console.log(tArr); và sau đó thực hiện

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

Có sai sót nào trong mã của tôi hay cách khác để thực hiện việc này. Cảm ơn!

Trả lời

13

Như bạn có thể biết, mọi thứ chạy không đồng bộ trong node.js. Vì vậy, khi bạn cần để có được những thứ để chạy theo một thứ tự nhất định, bạn cần phải sử dụng một thư viện kiểm soát hoặc về cơ bản thực hiện nó cho mình.

Tôi rất đề nghị bạn hãy xem async, vì nó sẽ dễ dàng cho phép bạn làm điều gì đó như thế này:

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

Những điều chính để xem ở đây là processEachTask được gọi với mỗi công việc, song song , do đó, thứ tự không được bảo đảm. Để đánh dấu rằng tác vụ đã được xử lý, bạn sẽ gọi callback trong chức năng ẩn danh từ findOne. Điều này cho phép bạn làm công việc không đồng bộ nhiều hơn trong processEachTask nhưng vẫn quản lý để biểu thị khi nó được thực hiện. Khi mọi công việc được thực hiện, sau đó nó sẽ gọi afterAllTasks.

Hãy xem async để xem tất cả các chức năng trợ giúp mà nó cung cấp, nó rất hữu ích!

+0

thay vì lặp qua result.tasks, chúng tôi có thể lặp lại đối tượng kết quả (JSON) không? tôi đã thử nhưng nó mang lại cho tôi một lỗi như Object # không có phương pháp 'foreach' và cũng thấy tất cả các chức năng trợ giúp của async nhưng không có chức năng cho lặp lại đối tượng. –

+0

Bạn có thể lặp qua một mảng có trong JSON ... có vẻ như bạn đã có một đối tượng, vì vậy bạn không thể lặp lại điều đó. Nếu bạn cần trợ giúp về việc xử lý đối tượng JSON, hãy đăng câu hỏi mới. – staackuser2

+3

Câu hỏi yêu cầu "Thực hiện tuần tự trong node.js". Điều này hoàn toàn ngược lại. Do đó tôi bỏ phiếu xuống –

5

Tôi vừa mới tạo ra một khái niệm trừu tượng đơn giản có tên là "wait.for" để gọi chức năng async trong chế độ đồng bộ hóa (dựa trên sợi): https://github.com/luciotato/waitfor

Sử dụng wait.for và async mã của bạn sẽ là:

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); 
    }); 
Các vấn đề liên quan