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