Javascript Promise 的竞争条件
Javascript Race condition for Promises
假设我有三个异步函数:
functionPromise1, functionPromise2, functionPromise3
我希望同时调用所有三个,详细信息如下:
- 如果
functionPromise1
被拒绝,停止其他两个函数
整理。
- 如果
functionPromise2
和 functionPromise3
都完成并已解决,请继续执行代码的下一部分,但如果 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.all
或 f1.then(() => Promise.all([f2, f3])
- 在使其变得更复杂之前不够好。
关于 "continue to the next part of the code",您实际上是在寻找 Promise.all
,它会等待所有内容并在任何承诺出现错误时立即拒绝:
return Promise.all([functionPromise1(), functionPromise2(), functionPromise3()]);
要在 functionPromise1()
拒绝时停止后两个进程,promises 无法为您处理任何事情,您需要手动完成。
假设我有三个异步函数:
functionPromise1, functionPromise2, functionPromise3
我希望同时调用所有三个,详细信息如下:
- 如果
functionPromise1
被拒绝,停止其他两个函数 整理。 - 如果
functionPromise2
和functionPromise3
都完成并已解决,请继续执行代码的下一部分,但如果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.all
或 f1.then(() => Promise.all([f2, f3])
- 在使其变得更复杂之前不够好。
关于 "continue to the next part of the code",您实际上是在寻找 Promise.all
,它会等待所有内容并在任何承诺出现错误时立即拒绝:
return Promise.all([functionPromise1(), functionPromise2(), functionPromise3()]);
要在 functionPromise1()
拒绝时停止后两个进程,promises 无法为您处理任何事情,您需要手动完成。