【问题标题】:Javascript Race condition for PromisesPromises 的 Javascript 竞争条件
【发布时间】:2023-03-23 17:04:01
【问题描述】:

假设我有三个异步函数:

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

【问题讨论】:

  • 当您说“同步”时,您的意思可能是“并发”吗?因为否则这个问题就没有意义了。
  • @john_omalley 我的意思是并发。我假设它们是同义词。我马上改
  • @mhodges 这不是说它们会异步运行吗?
  • 简短的回答是你不能。如果您希望调用 2 和 3 依赖于 1 解析,则在 1 完成之前不能调用它们。 JavaScript 具有 run-to-completion 函数语义,您不能在函数运行时取消函数调用,无论它是否在 Promise 中。您可以轻松完成其余的工作。
  • Promise 不能被“停止”,如果您正在执行任何可以停止的处理,则需要手动执行。请告诉我们您的functionPromise2functionPromise3 在做什么。

标签: javascript promise race-condition


【解决方案1】:

关于“继续执行代码的下一部分”,您实际上是在寻找 Promise.all,它等待所有内容并在任何承诺中出现错误时立即拒绝:

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

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2010-11-27
      • 2010-09-25
      • 1970-01-01
      • 1970-01-01
      • 2012-01-26
      • 2020-07-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-23
      相关资源
      最近更新 更多