当我在循环的每次迭代中进行异步调用时,我在尝试使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()获取管道数据(这是一个同步操作),并在回调中为快照数据发出请求请求(用于发出http请求的节点模块),我想要在将其推送到我的“orderData”数组之前附加到结果。当这一切都完成后,我用orderData调用“完成”,一个回调函数。如您所见,由于请求调用是异步的,因此在将任何数据添加到orderData数组之前调用done。
我认为我需要使用某种承诺才能在调用done之前保证结果,但是我没有成功实现对此函数的承诺。在q的文档中,似乎我想要使用的函数是promise.all(),它返回一个使用包含每个promise的履行值的数组来实现的promise,或者被拒绝与第一个被拒绝的承诺相同的拒绝理由。我没有看到如何将我的forEach循环转换为promises数组。我也在查看async parallel function并遇到了与函数数组相同的问题。
非常感谢任何帮助。谢谢!
答案 0 :(得分:3)
要构建一个Promise数组以便在Promise.all
中使用,您可以跨越商店数组map
,再次跨订单数组,为每个将被解析的订单返回Promise或根据{{1}}的结果拒绝。合并生成的嵌套数组会为您提供一个promises数组,然后可以将其传递给requestify.request
。
使用您的示例:
Promise.all