[英]How do I wait until an asynchronous process inside a loop is finished before exiting the loop?
我在JavaScript forEach
循環中運行一些異步代碼。 我想等到異步進程中的代碼運行完畢,然后再執行循環。
下面的例子:
ids
是一個字符串數組。 db
是我創建的用於MongoDB的節點模塊
var appIdsNotFound = "";
var count = 0;
ids.forEach(function(id) {
output[count] = {};
//console.log(id);
db.findApp(id, function(error, result) {
if(error) {
fatalError = true;
console.log(error);
} else {
if (result) {
output[count] = result;
//console.log(output[count]);
count++;
} else {
appNotFound = true;
appIdsNotFound += id + ", ";
console.log(appIdsNotFound);
}
}
});
});
//more code that we want to wait before executing
有沒有一種方法可以等待執行循環外的其余代碼,如果可以的話,我將如何去做。
假設db
是用於訪問db
的某個模塊,請嘗試查找同步版本。 這假定您對同步沒問題,因為您正試圖以這種方式編寫它,因此請等一切之后再繼續。
如果您的數據庫庫使用promise,則可以將其與Promise.all
結合使用。 對每個項目發出請求,將其所有諾言收集到一個數組中,並將其提供給Promise.all
。 Promise.all
的諾言將在所有諾言Promise.all
解決時解決。
const promises = ids.map(id => db.promiseReturningFindApp(id)); const allRequests = Promise.all(promises).then(responses => { // responses is an array of all results });
如果您沒有API的承諾返回版本, db.findApp
包裹在promise中,執行建議2。
function promiseReturningFindApp(id){ return new Promise((resolve, reject) => { db.findApp(id, (error, result) => { if(error) reject(error); else resolve(result); }); }); }
選項2和3是異步的,因此,從技術上講,您不要“等待”。 因此,需要在之后執行的代碼只能駐留在回調中。
您可以將每個項目變成一個函數並使用async :
var async = require('async');
var output = [], appsNotFound = [];
var appRequests = ids.map((id) => (cb) => {
db.findApp(id, (error, result) => {
if (error) {
appsNotFound.push(id);
return cb();
}
output.push(id);
return cb();
})
})
async.parallel(appRequests, () => {
console.log('N# of Apps found',output.length);
console.log("Ids not found:",appIdsNotFound.join(','))
console.log("N# Apps not found:",appIdsNotFound.length)
})
如果數據庫無法處理,請嘗試使用async.serial
。
如果願意,可以用promise做類似的事情,但這需要更少的代碼行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.