2017-10-07 92 views
-1

我有一個擁有20000+個承諾的大集合,我想用Bluebird的Promise.map來解決它。但是,我的代碼不能成功執行,但在大約15-20分鐘後超時。Nodejs Bluebird Promise.map不適用於大集合

我得到的錯誤是超時錯誤。

當集合少於2000個承諾時,代碼將在不到10秒內成功執行。

請幫我找到Promise.map或其他任何方式的替代方法,以便代碼不超時。

service.getSomePromises().then(function(arrSomePromises){ 
    var promises = []; 
    for (var i = 0;i < arrSomePromises.length; i++){ 
     var getDetailsObject = _getDetails(_db, i); 
     promises.push(getDetailsObject); 
    } 

    //Below is the code that times out 
    return Promise.map(promises, function(doc){ 
     return reportData.push(doc); 
    }) 
} 
+0

您可能會嘗試太多的併發連接,這可能會耗盡本地資源或壓倒目標。我建議在'Promise.map()'中使用'concurrency'選項。首先將它設置爲像10這樣的小東西,如果可以的話,然後試着提高它。 – jfriend00

+0

此外,現在你已經添加了代碼,這是使用'Promise.map()'的錯誤方法。通常情況下,您會傳遞一組數據和一個函數,對該數據執行一些異步操作並返回一個承諾。你不會傳遞一系列的承諾。我們可以使用'Promise.all()'和一組promise。 – jfriend00

+0

您顯示的代碼沒有任何意義,因爲'promise.length'爲'0',所以'for'循環將不會執行任何操作。 – jfriend00

回答

0

如果您收到超時錯誤,那麼你可能只是壓倒了太多的併發請求的一些主機目標服務器。對於大量請求,您需要同時限制同時發送多少個同時請求到同一個主機。我建議一次開始時限制在5-10左右,然後你可以嘗試提高它,看看它是否能夠提高你的表現。目標服務器對同時有多少個同時請求可以同時提供全部服務的限制。高於這個數字只會加重基礎設施負擔,最終導致超時錯誤。

Bluebird的Promise.map()正確使用時(你沒有做)有一個concurrency選項,它會告訴它你希望它立即使用的最大併發連接數。但是,要使用該選項,必須正確使用Bluebird.map(),並在其中傳遞一組數據(而不是您已經開始異步操作的承諾數組)以及返回承諾的函數這些數據項之一。

下面是如何正確使用Promise.map()concurrency選項的示例。

let someLargeArrayOfData = [...]; 
Promise.map(someLargeArrayOfData, function(item) { 
    return request(item);  // async function that returns promise 
}, {concurrency: 10}).then(function(results) { 
    // results is an array of data from all the resolved promises 
}).catch(function(err) { 
    // process error here 
}); 
+0

感謝您的回覆。我將嘗試更新代碼以處理數據數組而不是承諾。但是,如果我有一系列的承諾,有沒有辦法與他們合作,除了promises.all? – user2434285

+1

@ user2434285 - 一個promise數組通常表示一組已經啓動的異步操作。在那個時候,除了當Promise.all()所做的事情完成時,沒有什麼可以瞭解的。您需要一種不會一次啓動太多異步操作的解決方案。 – jfriend00

相關問題