async.each 的承诺未按预期工作

Promises not working as expected with async.each

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

    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 returns 承诺并在后台使用 Knex 更新,这也是 returns 一个承诺。 我希望上面代码的输出是:

Updated
Updated
Finished
Done

但我得到的输出是:

Done
Updated
Updated

所以,async.each 的回调不工作,代码不等待 async.each完成。

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

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

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');

根本不要将 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');