簡體   English   中英

在退出循環之前,如何等待直到循環中的異步過程完成?

[英]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

有沒有一種方法可以等待執行循環外的其余代碼,如果可以的話,我將如何去做。

  1. 假設db是用於訪問db的某個模塊,請嘗試查找同步版本。 這假定您對同步沒問題,因為您正試圖以這種方式編寫它,因此請等一切之后再繼續。

  2. 如果您的數據庫庫使用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 }); 
  3. 如果您沒有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM