2011-07-20 40 views
8

Tôi có một vòng lặp có cuộc gọi không đồng bộ bên trong nó, với một cuộc gọi lại. Để có thể di chuyển, tôi cần gọi lại để kích hoạt toàn bộ vòng lặp, sau đó hiển thị kết quả của vòng lặp.Node.js: đang chờ các cuộc gọi lại trong một vòng lặp trước khi di chuyển trên

Mọi cách tôi đã cố gắng kiểm soát điều này không hiệu quả (đã thử Bước, Tame.js, async.js và những người khác) - mọi đề xuất về cách tiến lên?

array = ['test', 'of', 'file']; 
array2 = ['another', 'array']; 

for(i in array) { 
    item = array[i]; 
    document_ids = new Array(); 

    for (i2 in array2) { 
     item2 = array2[i2]; 
     // look it up 
     mongodb.find({item_name: item2}).toArray(function(err, documents { 
      // because of async, 
      // the code moves on and calls this back later 
      console.log('got id'); 
      document_ids.push(document_id); 
     })) 
    } 

    // use document_ids 
    console.log(document_ids); // shows [] 
    console.log('done'); 
} 

// shows: 
// [] 
// done 
// got id 
// got id 

Trả lời

10

Bạn đang ghi lại document_ids trước khi gọi lại. Bạn phải theo dõi số lượng cuộc gọi lại mà bạn đã chạy để biết khi nào bạn hoàn tất.

Phương pháp dễ dàng là sử dụng bộ đếm và để kiểm tra số lượng trên mỗi lần gọi lại.

Lấy ví dụ của bạn

var array = ['test', 'of', 'file']; 
var array2 = ['another', 'array']; 
var document_ids = []; 

var waiting = 0; 

for(i in array) { 
    item = array[i]; 

    for (i2 in array2) { 
     item2 = array2[i2]; 
     waiting ++; 

     mongodb.find({item_name: item2}).toArray(
      function(err, document_id) { 
       waiting --; 
       document_ids.push(document_id); 
       complete(); 
      }) 
     ); 
    } 
} 

function complete() { 
    if (!waiting) { 
     console.log(document_ids); 
     console.log('done');  
    } 
} 
+1

Cảm ơn bạn rất nhiều! Tôi đã sửa đổi điều này với sự trợ giúp của async.js và làm cho nó hoạt động. –

Các vấn đề liên quan