【问题标题】:How to halt execution until Promise is resolved如何在 Promise 解决之前暂停执行
【发布时间】:2021-05-01 09:29:15
【问题描述】:

我刚开始使用 Promise,到目前为止它们都很棒。但是,我目前正在编写的软件要求我收集所有的 Promise 并获得它们的聚合结果。这个过程必须在代码继续执行之前完成,因为未来的执行取决于结果。

对于一个验证框架,我以 Promise 的形式发出验证请求,这些请求被存储(并且是异步的)在一个数组中。当我单击提交按钮时,它应该等待所有验证承诺,并且只有在所有承诺都成功解决时才执行。这是通过以下代码完成的,它应该返回 false,但不幸的是返回 true:

console.log(valid());

function valid() {
  // ...
  some_prev = true;
  pending = [
    new Promise(function(resolve) {
      setTimeout(function() {console.log('done resolve'); resolve(true);}.bind(this), 2000);
    }),
    new Promise(function(reject) {
      setTimeout(function() {console.log('done reject'); reject(false);}.bind(this), 4000);
    })
  ];
  
  if (some_prev && collectPending(pending).then(val => {return true;}).catch(err => {return false;})) {
    return true;
  } else {
    return false;
  }
}

function collectPending(pending) {
  var p = Promise.all(pending)
    .then(values => {
      return true;
    })
    .catch(error => {
      return false;
    });
    
  return p;
}

valid 方法应返回 true,否则表单将在包含错误时提交。

我也尝试将 Promise.all 包装在异步函数中,但我发现这只会进一步推动问题,最终您总是会遇到类似的情况。

本质上,是否需要等待直到所有承诺都得到解决才能停止执行?

编辑 27-01-2021 15:38: 当我扩展一个框架时,我只被允许覆盖valid 方法。该框架的其余部分期望valid 方法是同步的。 所以我真的在寻找一种将异步转换回同步的方法,而不是让所有代码异步。我自己编写的 collectPending 方法,所以这个可以更改,而不是 @987654327 @方法。

【问题讨论】:

    标签: javascript asynchronous promise async-await


    【解决方案1】:

    这项工作是否符合您的期望,它正在按照您可能想要的顺序执行。

    valid().then(res => console.log(res));
    
    async function valid() {
      // ...
      some_prev = true;
      pending = [
        new Promise(function(resolve) {
          setTimeout(function() {
            console.log('done resolve');
            resolve(true);
          }.bind(this), 2000);
        }),
        new Promise(function(reject) {
          setTimeout(function() {
            console.log('done reject');
            reject(false);
          }.bind(this), 4000);
        })
      ];
      // wait for collectPending to resolve 
      if (some_prev && await collectPending(pending)) {
        return true;
      } else {
        return false;
      }
    }
    
    async function collectPending(pending) {
      let result = await Promise.all(pending);
      return result.reduce((res, current) => res && current); //combines result of all the promises and return the boolean 
    }

    【讨论】:

    • 感谢您的回答,不幸的是,这不起作用,因为我正在扩展一个框架,我只能覆盖valid 方法。所以我真的在寻找一种将异步转换回同步的方法。
    • 好吧,如果你想要valid的结果,并且它本身就是一个异步函数,即处理promise,valid()在不使用then的情况下永远不会工作
    • 如果我们不能修改collectPending,我们可以管理,你要我修改答案吗?
    • 那很不幸..我认为将异步转换回同步是执行的常规操作?无论如何,collectPending 方法可以根据需要进行更改,因为它是我自己编写的方法,并且仅在覆盖的valid 方法中调用。
    • 如果你想使用promises那么我更喜欢这种方式,否则我们总是可以做回调
    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    • 2015-09-05
    • 1970-01-01
    • 2019-05-28
    相关资源
    最近更新 更多