承诺的{Javascript种族条件

时间:2017-01-31 18:13:18

标签: javascript promise race-condition

假设我有三个异步函数:

functionPromise1, functionPromise2, functionPromise3

我希望同时调用所有三个,并提供以下详细信息:

  • 如果functionPromise1被拒绝,请停止其他两个功能 精加工。
  • 如果functionPromise2functionPromise3都已完成并已解决,请继续执行代码的下一部分,但如果functionPromise1最终被拒绝,则不要继续进入代码
  • 如果拒绝functionPromise2functionPromise3,请不要继续使用代码的下一部分。

我对这些函数的用例是functionPromise1作为输入验证,我希望与其他函数同步,将输入视为已经过验证,以加快我的进程。但是,如果functionPromise1发现输入无效,我想终止代码。

function functionPromise2(...){
    return new Promise(function(resolve,reject){
        fetchUrl(url, function(err, meta, body){
            if (err) { reject(err); } else {
                if (body.toString().indexOf(text) !== -1){
                    resolve();
                } else {
                    reject("Could not find quote");
                }
            }
        });
    });
}

function functionPromise3(...) {
    return new Promise(function(resolve,reject){
        var id = shortid.generate();
        var fileName = id+'.png';
        webshot(url, fileName, { shotOffset: {left: mouseX, top: mouseY} }, function(err) {
            if (err) { reject(err); } else {
                resolve({id: id, fileName: fileName});   
            }
        });
    });
}

2 个答案:

答案 0 :(得分:2)

关于“继续下一部分代码”,你实际上是在寻找等待一切的Promise.all,如果任何承诺中有错误,立即拒绝:

return Promise.all([functionPromise1(), functionPromise2(), functionPromise3()]);

要在functionPromise1()拒绝时停止后两个进程,承诺无法为您处理,您需要手动执行此操作。

答案 1 :(得分:0)

这个问题的答案实际上取决于functionPromise2和functionPromise3的功能。如果两者都只执行一次I / O操作,那么您只想使用Promise.all([f1, f2, f3])。如果它们涉及更多(即多次回调),那么你需要保持状态以保存第一个承诺的结果并在第二个和第三个承诺的中间步骤中检查它。

你无法在单线程Javascript中真正拥有真正的竞争条件。为了简单起见,我会确保直截了当的解决方案 - Promise.allf1.then(() => Promise.all([f2, f3]) - 在使其变得更复杂之前还不够好。