Promise Chaining Race-Condition

问题描述 投票:2回答:1

我目前正在研究一种相当简单的逻辑,用于处理排队的ZPL打印作业,这些作业存储在一个数组中,然后进行迭代,每个作业向打印机发送n份副本。

我将阵列简化为一个承诺链,在每个作业的子链中混合,然后将副本发送到打印机。对打印机的调用是同步的(是的,我知道...),因此我将它们中的每一个都包装到Promise中,该Promise仅在打印机收到副本时才解决,从而确保顺序处理。

[如果传输失败,则当前的承诺将因手工错误而被拒绝,而该错误被捕获在主链中。

到目前为止,理论上,子链之间似乎存在一种竞争条件。

我已尽力而为,但我根本看不到...

[这里有一些简化的代码+提琴,请注意子链如何不随后运行:

['job1', 'job2'].reduce((pMain, item, curIndex) => {

    var pSub = Promise.resolve();

    for (let i = 0; i < 2; i++) pSub = pSub.then(() => new Promise((resolve, reject) => setTimeout(reject, 2000)));

    return pMain.then(() => pSub);

}, Promise.resolve())
.then(() => /* print all done */)
.catch( handleError );

jsfiddle with console.logs here

任何建议都受到高度赞赏。被困在如此琐碎的事情上真是令人讨厌。

javascript es6-promise race-condition
1个回答
1
投票

您的pSub链均已创建,并在reduce调用期间同步运行。为了变得连续,它们需要进入then回调:

['job1', 'job2'].reduce((pMain, item, curIndex) => {
    return pMain.then(() => {
        var pSub = Promise.resolve();
        for (let i = 0; i < 2; i++)
            pSub = pSub.then(() => new Promise((resolve, reject) => setTimeout(reject, 2000)));
        return pSub;
    });
}, Promise.resolve())

或者在两个循环之间仅构建一条链:

['job1', 'job2'].reduce((promise, item, outerIndex) => {
    return Array.from({length: 2}).reduce((promise, _, innerIndex) => {
        return promise.then(() => new Promise((resolve, reject) => setTimeout(reject, 2000)));
    }, promise);
}, Promise.resolve())
© www.soinside.com 2019 - 2024. All rights reserved.