Javascript 循环内部的异步函数调用
当我在循环的每次迭代中进行异步调用时,我在尝试使for循环同步运行时遇到了一个问题 这是我的密码:Javascript 循环内部的异步函数调用,javascript,arrays,node.js,asynchronous,Javascript,Arrays,Node.js,Asynchronous,当我在循环的每次迭代中进行异步调用时,我在尝试使for循环同步运行时遇到了一个问题 这是我的密码: pipeline: function(userContext, options, done){ var orderData = []; options.data.forEach(function(store, index){ store.orders.forEach(function(order){ shopify.getPipeline
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包含一个存储阵列,每个存储包含一个订单阵列。对于每个订单,我都会调用shopfify.getPipeline()以获取管道数据(这是一个同步操作),并在回调中对快照数据发出requestify请求(用于发出http请求的节点模块),我希望在将快照数据推送到“orderData”数组之前将其附加到结果中。当这一切完成后,我将使用orderData调用“done”,一个回调函数。如您所见,由于requestify调用是异步的,所以在将任何数据添加到orderData数组之前都会调用done
我认为在调用done之前,我需要使用某种承诺来保证结果,但是我没有成功地将承诺实现到这个函数中。在的文档中,我想要使用的函数似乎是promise.all(),它“返回一个承诺,该承诺通过包含每个承诺的实现值的数组来实现,或者以与第一个要拒绝的承诺相同的拒绝原因被拒绝”。我没有看到如何将我的forEach循环转换为一系列承诺。我还查看了,并遇到了关于函数数组的相同问题
非常感谢您的帮助。谢谢 要构建一个承诺数组,用于
Promise.all
,您可以在门店数组中映射
,然后再次在订单数组中映射,为每个订单返回一个承诺,该承诺将根据requestify.request
的结果得到解决或拒绝。合并生成的嵌套数组将为您提供一个承诺数组,然后可以将该数组传递给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);
});
}