Javascript Promise 的竞争条件

Javascript Race condition for Promises

假设我有三个异步函数:

functionPromise1, functionPromise2, functionPromise3

我希望同时调用所有三个,详细信息如下:

我对这些函数的用例是 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});   
            }
        });
    });
}

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

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

关于 "continue to the next part of the code",您实际上是在寻找 Promise.all,它会等待所有内容并在任何承诺出现错误时立即拒绝:

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

要在 functionPromise1() 拒绝时停止后两个进程,promises 无法为您处理任何事情,您需要手动完成。