【问题标题】:Asynchronous function call inside for loopfor循环内的异步函数调用
【发布时间】:2015-11-14 14:17:14
【问题描述】:

当我在循环的每次迭代中进行异步调用时,尝试使我的 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 调用回调函数“完成”。如您所见,由于 requestify 调用是异步的,所以在将任何数据添加到 orderData 数组之前调用了 done。

我认为我需要在调用 done 之前使用某种 promise 来保证结果,但是我在这个函数中实现 promise 没有成功。在q 的文档中,我想要使用的函数似乎是promise.all(),它'返回一个由包含每个promise 的履行值的数组履行的promise,或者被相同的拒绝拒绝原因作为第一个被拒绝的承诺”。我看不到如何将我的 forEach 循环转换为一系列承诺。我也在查看async parallel function 并在函数数组方面遇到了同样的问题。

非常感谢任何帮助。谢谢!

【问题讨论】:

    标签: javascript arrays node.js asynchronous


    【解决方案1】:

    要构造一个用于Promise.all 的 Promise 数组,您可以 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);
        });
    }
    

    【讨论】:

      猜你喜欢
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      • 2011-12-03
      • 1970-01-01
      • 2017-12-16
      • 2020-07-13
      • 2012-10-31
      • 2021-09-11
      相关资源
      最近更新 更多