2012-11-26 37 views
3

我有一個ajax調用是在另一個函數內的forEach循環內。 問題是,外部函數的回調在內部循環結束之前觸發 - 所以「staticItemList」在傳遞給回調函數時沒有填充項目。 我該如何解決這個問題?我真的花了很多時間。謝謝。ajax裏面的forEach循環,內部回調火災後完成

exports.buildTheList = function (parsedList, callback) { 
     var staticItemList = {}; 
     parsedList.forEach(function(parsedItem) { 

       db.staticList.find({"_id":parsedItem.ID}).forEach(function(err, doc) { 
        if (!doc){ 
         console.log("newStaticItem not found in db"); 
         parsedDataFetcher.fetchParsedDetails(Path, function(parsedDetails){ 
          staticItemList["_id"] = parsedItem.ID; 
          staticItemList[parsedItem.ID] = { 
            "_id": parsedItem.ID, 
            "type": parsedItem.type, 
            } 
           }) 

          }else { 
            console.log("newStaticItem already found in db"); 
          } 
       }); 
      }); 


     callback(staticItemList); 
    } 

回答

5

在循環內部添加一個計數器變量,並在每次異步方法完成時遞減計數器變量。一旦計數器達到零,就調用回調函數。在僞代碼中:

var counter = 0; 
foreach(function() { 
    counter++; 
    doAsync(function() { 
      // add to list 

      counter--; 
      if (counter === 0) { 
       callback(list); 
      } 
    }); 
} 

希望有幫助。

+0

但我不知道從「db.staticList.find({」_ id「:parsedItem.ID})返回的數組長度是多少?」 - 是不是一個問題? – Daniel

+0

@Daniel,你只需要將該數組放入一個變量,得到它的長度,然後執行foreach就可以了。 –

0

AJAX發生異步,所以會發生什麼是你的循環運行,觸發所有的AJAX調用,然後完成,調用你的回調。您可能需要在您的foreach循環中實現某種計數器,並檢查每次AJAX調用的完成情況。一個已完成的AJAX調用的數量與計數器的數量相同,您可以在異步函數上下文中執行回調函數。

1

我想看看dojo promise all。從手冊:

dojo/promise/all是一個函數,採用多承諾和 返回時,所有的承諾已 應驗已成立的新承諾。

該頁面上的示例演示瞭如何執行您所需的操作。