代码之家  ›  专栏  ›  技术社区  ›  Sandeepan Nath

无法使用async.each()在具有异步块的数组上异步迭代

  •  0
  • Sandeepan Nath  · 技术社区  · 7 年前

    我想为数组中的每个元素执行一些异步功能 currencyData 如下所示。我有以下逻辑-

    exports.getCurrenciesOfMerchant(req,res,function(currencyData)
    {
         async.each(currencyData, function (eachCurrency) {
            fieldObject.currencyId=eachCurrency;
            console.log("See currencyData "+fieldObject.currencyId);
    
    //async block starts here   
            couponHandler.checkIFWalletExists(res,fieldObject,function(fieldObject)
            {
                console.log("checked wallet for curr "+fieldObject.currencyId);
                if(fieldObject.hasWallet == 0)
                {
                    exports.createWalletForUser(fieldObject,res,function(fieldObject,res){
    //                        exports.createCoupon(fieldObject,res,function(res,fieldObject,couponId){
    //                            return exports.couponCreationResponse(res,fieldObject,couponId);
    //                        });
                        console.log("created wallet");
                    });
                }
            });
        });
    });
    

    以下是输出-

    See currencyData 5
    See currencyData 6
    checked wallet for curr 6
    checked wallet for curr 6
    created wallet
    created wallet
    

    正如可以看到的,Asic.Ech()在异步块完成执行之前取值6。它从未真正运行过值5的逻辑。

    我想这是async.each()有用的地方。但是,我做不到。试用 async.forEachOf 但结果是一样的。

    2 回复  |  直到 7 年前
        1
  •  0
  •   noppa    7 年前

    您没有调用提供的“完成”回调,因此 async 不知道异步操作已完成,并且不会继续处理其余项。将迭代器更改为

    async.each(currencyData, function (eachCurrency, done) {
    

    打电话给 done -函数。

    exports.createCoupon(fieldObject,res,function(res,fieldObject,couponId){
        var res = exports.couponCreationResponse(res,fieldObject,couponId);
        done();
        return res;
    });
    

    编辑: ……当然,如果有条件的话,也在你的其他分支。

    } else {
       done();
    } 
    

    如果不希望同时处理项目,请使用 async.eachLimit 而是:

    async.eachLimit(currencyData, 1, function (eachCurrency, done) {
    
        2
  •  0
  •   Andrii Litvinov    7 年前

    这个 doc 说:

    并行地将函数迭代器应用于coll中的每个项。这个 使用列表中的一个项调用iteratee,并为when调用回调 已经结束了。如果迭代器将错误传递给其回调,则 主回调(对于每个函数)立即用 错误。

    注意,由于此函数将iteratee应用于 并行的,不能保证迭代器函数 按顺序完成。

    我想方法是 couponHandler.checkIFWalletExists 在你的代码中没有被注释掉。这意味着迭代器将在完成第一个项的处理之前开始处理第二个项。可能是因为第二个项目处理得更快,所以您会看到结果的顺序错误。