簡體   English   中英

for循環內的異步函數調用

[英]Asynchronous function call inside for loop

我在循環的每個迭代中進行異步調用時都試圖使我的for循環行為同步時遇到問題。

這是我的代碼:

pipeline: function(userContext, options, done){

    var orderData = [];

    options.data.forEach(function(store, index){
        store.orders.forEach(function(order){
            shopify.getPipeline(userContext, {'order':order,'storeId':index}, function(result){
                var snapshotId = "30775bf1bb854c5d84c9c2af37bc8fb0";
                var resourceToQuery = config.structrUrls.getUrl("ConfigurationSnapshot") + '/' + snapshotId ;
                var requestOptions = {
                    method: "GET",
                    timeout: 8000
                };
                requestify.request(resourceToQuery, requestOptions)
                    .then(function(snapshotResult){
                        result.snapshots = snapshotResult.getBody().result;
                        result.snapshots.configurationPayload = JSON.parse(snapshotResult.getBody().result.configurationPayload);
                        orderData.push(result);
                    })
                    .catch(function(err){
                        console.log (err);
                        done(err);
                    });
            });
        });
    });

    done(null, orderData);

}

我在這里了解問題,但不知道如何解決。 讓我解釋一下功能:

options.data包含一個存儲數組,每個存儲包含一個訂單數組。 對於每個訂單,我正在調用shopify.getPipeline()來獲取管道數據(這是一個同步操作),並且在回調中我向快照數據發出一個requestify請求(用於發出http請求的節點模塊),我想將結果追加到我的“ orderData”數組之前。 所有這些完成后,我將使用orderData調用回調函數“ done”。 如您所見,由於requestify調用是異步的,因此在將任何數據添加到orderData數組之前將調用done。

我認為我需要使用某種promise才能在調用完成之前保證結果,但是在將promise實現到此函數中我一直沒有成功。 q的文檔中,似乎我要使用的函數是promise.all(),該函數“返回一個諾言,該諾言通過包含每個諾言的實現值的數組來實現,或者由於相同的拒絕原因而被拒絕作為被拒絕的第一個諾言”。 我沒有看到如何將我的forEach循環轉換成一個Promise數組。 我也在看異步並行函數,並在函數數組方面遇到了同樣的問題。

任何幫助是極大的贊賞。 謝謝!

要構建Promise.all使用的Promises數組,您可以在商店的整個數組中進行map ,並在訂單的整個數組中進行map ,為每個訂單返回Promise,將根據requestify.request的結果來解決或拒絕該訂單。 合並生成的嵌套數組將為您提供一個promise數組,然后將其傳遞給Promise.all

使用您的示例:

pipeline: function(userContext, options, done){
    var nestedPromises = options.data.map.forEach(function(store, index){
        return store.orders.map(function(order){
            return new Promise(function(resolve, reject){
                shopify.getPipeline(userContext, {'order':order,'storeId':index}, function(result){
                    var snapshotId = "30775bf1bb854c5d84c9c2af37bc8fb0";
                    var resourceToQuery = config.structrUrls.getUrl("ConfigurationSnapshot") + '/' + snapshotId ;
                    var requestOptions = {
                        method: "GET",
                        timeout: 8000
                    };
                    requestify.request(resourceToQuery, requestOptions)
                        .then(function(snapshotResult){
                            result.snapshots = snapshotResult.getBody().result;
                            result.snapshots.configurationPayload = JSON.parse(snapshotResult.getBody().result.configurationPayload);
                            resolve(result);
                        })
                        .catch(function(err){
                            reject(err);
                        });
                });
            });
        });
    });
    // Flatten nested array.
    var promises = Array.prototype.concat.apply([], nestedPromises);
    Promise.all(promises).then(function(orderData){
        done(null, orderData);
    }).catch(function(err){
        done(err);
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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