【问题标题】:Waiting on asynchronous function within promise在 Promise 中等待异步函数
【发布时间】:2018-09-06 20:23:05
【问题描述】:

以下情况:

function myFunction() {

      return new Promise(function (resolve, reject) {

          doSomething();
          let myVariable = doSomethingElse();

          let otherVariable = doOtherThings(myVariable);              

          return resolve(otherVariable);
      });
}

现在,我希望 myVariable 不是由函数调用初始化,而是在回调中,或者更确切地说,在异步函数返回的 Promise 的 .then 中。

function myFunction() {

      return new Promise(function (resolve, reject) {

          doSomething();
          let myVariable;

          asynchronousFunctionThatReturnsPromise().then(function(param) {
             myVariable = doSomethingElse(param);
          });

          let otherVariable = doOtherThings(myVariable);              

          return resolve(otherVariable);
      });
}

理想情况下,外部函数会等到 myVariable 被赋值,直到它执行doOtherThings(myVariable),但我想这在 javascript 中是不可能的。

不幸的是,我不能简单地将以下所有代码放在“回调”函数中,因为外部函数返回依赖于结果。

有没有办法可以处理这个问题,理想情况下无需更改外部函数 (myFunction) 上的任何内容?

【问题讨论】:

  • 将依赖myVariable的代码放入.then()回调中。这包括resolve() 电话。你的 myFunction() 调用已经返回了一个 Promise 实例,所以任何调用它的东西都必须使用它自己的 .then() 回调。
  • 哦,你不必return 来自resolve() 的返回值。它不会伤害任何东西,但它也不会做任何有用的事情。

标签: javascript asynchronous ecmascript-6 async-await es6-promise


【解决方案1】:

完全摆脱 promise 包装器。这是一个promise anti-pattern 将一个承诺包装在另一个承诺上。相反,只需返回您已有的并将您的逻辑放入 .then() 处理程序中:

function myFunction() {
        doSomething();

        return asynchronousFunctionThatReturnsPromise().then(function(param) {
           let myVariable = doSomethingElse(param);
           let otherVariable = doOtherThings(myVariable);              
           return otherVariable;
        });
    });
}

用法:

myFunction().then(val => {
   console.log(val);        // will be the value of otherVariable above
}).catch(err => {
   console.log(err);
});

不幸的是,我不能简单地将以下所有代码放在“回调”函数中,因为外部函数返回依赖于结果。

不清楚这是什么意思。您必须更改外部函数才能正确写入myFunction()

有什么方法可以处理这个问题,理想情况下无需更改外部函数 (myFunction) 上的任何内容?

没有。您应该修改 myFunction 以正确编写代码。如果你有一些现实世界的情况,有一些现实世界的限制,那么你必须用这些实际细节和真实代码(不是伪代码)发布一个不同的问题,以便我们更具体地为你提供建议。

【讨论】:

  • 嗯,好吧,有道理
  • 好吧,myFunction 不应该返回 resolve(xyz) 以外的任何东西,我无权访问调用 myFunction 的位置。
  • “不。你应该修改 myFunction 以正确编写代码” - 好的,这就是我想知道的。
  • @Ferenjito - 您的示例返回一个承诺。我的示例返回一个承诺。它们对调用者来说是一样的,除了我的例子在你的例子中不能正常工作,而且我的例子避免了常见的 Promise 反模式。
  • @Ferenjito - 同样重要的是要了解您使用的承诺反模式的一个后果是,如果asynchronousFunctionThatReturnsPromise() 拒绝它的承诺,您的代码将默默地忽略该拒绝。调用者永远不会看到被拒绝的承诺,因为您包裹在asynchronousFunctionThatReturnsPromise() 周围并返回的承诺不会跟踪拒绝,这是一个严重的错误。在我的示例中不会发生这种情况。这是使用反模式的主要问题之一(除了不必要的额外复杂性)。
猜你喜欢
  • 2020-03-24
  • 1970-01-01
  • 2017-01-15
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-04
相关资源
最近更新 更多