【问题标题】:Promises not working as expected with async.each使用 async.each 的 Promise 无法按预期工作
【发布时间】:2017-01-18 00:33:09
【问题描述】:

我不知何故无法找到解决方案。这是我正在做的事情:

    async.each(bottles, function(bottle) {
        // set substance quantity to 0
        updateQuantity(bottle[constant.SUBSTANCE_ID], 0)
            .then(function() {
                bottle[constant.EXPIRY] = expiry;
                bottle[constant.IS_AVAILABLE] = true;

                updateRecord(bottle)
                    .then(function() {
                        console.log('Updated');
                    },
                    function() {});
            }, function() {});
    }, function() {
        console.log('Finished');
    });
    console.log('Done');

方法 updateQuantity 和 updateRecord 返回承诺,并在后台使用 Knex 更新,这也返回承诺。 我希望上面代码的输出是:

Updated
Updated
Finished
Done

但我得到的输出是:

Done
Updated
Updated

所以,async.each 的回调不起作用,代码没有等待 async.each 完成。

【问题讨论】:

  • async.js 不适用于承诺。不要使用它。
  • 你为什么要使用那些无操作函数?
  • @Bergi 除了 async.js 还有什么建议吗?
  • @Ashutosh 检查我的答案

标签: node.js promise async.js


【解决方案1】:

不要将 async.js 与 Promise 一起使用,它们的内置方法可以满足您的需求,并且您无需回退到回调。

bottles.reduce(function(prev, bottle) {
    return prev.then(function() {
        // set substance quantity to 0
        return updateQuantity(bottle[constant.SUBSTANCE_ID], 0)
    }).then(function() {
        bottle[constant.EXPIRY] = expiry;
        bottle[constant.IS_AVAILABLE] = true;
        return updateRecord(bottle);
    }).then(function() {
        console.log('Updated');
    });
}, Promise.resolve()).then(function() {
    console.log('Finished successfully');
}, function(err) {
    console.error(err)
}).then(function() {
    console.log('Done'); // notice you must put this in the callback
});
console.log('Started');

【讨论】:

    【解决方案2】:

    您必须从async.each 操作中调用传入的callback。实际上,异步不知道您的回调何时解决。

    此外,DONE 应该始终是您看到的第一个文本,因为 async.each 不会阻止。当您开始运行脚本时,async.each 将被注册,但由于您的代码是异步的,它会在updateRecordupdateQuantities 完成之前到达console.log('Done')

    async.each(bottles, function(bottle, callback) {
        updateQuantity(bottle[constant.SUBSTANCE_ID], 0)
            .then(function() {
                ...
    
                updateRecord(bottle)
                    .then(function() {
                        console.log('Updated');
                        callback();
                    },
                    function() {});
            }, function() {});
    }, function() {
        console.log('Finished');
    });
    console.log('Done');
    

    【讨论】:

    • 非常感谢 megawac,刚刚在文档中也确认了您的回答 :)
    • 这不处理失败。
    • OP 要求在 promise 中正确使用 async.each。确保适当地处理失败是其中的一部分。
    • OP 询问问题是什么以及解决方案,而不是询问如何正确处理异步文档中详细介绍的错误状态和控制流。
    猜你喜欢
    • 2014-05-24
    • 1970-01-01
    • 2020-11-22
    • 2013-12-23
    • 2014-12-09
    • 2016-01-13
    • 2020-09-21
    • 2011-08-17
    • 2012-04-29
    相关资源
    最近更新 更多