【问题标题】:async/await in a class method called "then"async/await 在名为“then”的类方法中
【发布时间】:2017-04-28 22:33:14
【问题描述】:

我创建了一个具有“then”方法的类。该类与 Promise 类型无关; "then" 方法有不同的目的,并且不返回承诺。我正在尝试在 Typescript 2.1.4 中编写一个 async/await 函数来等待并返回此类的一个实例,但是 VS Code 中的 Typescript 服务器给了我错误。如果我将方法重命名为“then”以外的名称,错误就会消失。

有错误的示例代码:

class MyClass {
    then(): number {
        // this method isn't related to Promise.then
        return 2 + 2;
    }
}

// three errors below go away when "then" is renamed

// [ts] An async function or method must have a valid awaitable return type.
async function my_async(): Promise<MyClass> {
    let a: Promise<MyClass> = Promise.resolve(new MyClass());

    // [ts] Operand for 'await' does not have a valid callable 'then' member.
    let b: MyClass = await a;

    // [ts] Return expression in async function does not have a valid callable 'then' member.
    return b;
}

有人可以解释为什么不允许对具有自己的“then”方法的对象使用承诺,或者解决方法吗?

【问题讨论】:

  • 你没有说错误是什么。这很重要。
  • @Carcigenicate 谢谢,我的错!
  • 请同时发布代码。该错误似乎与您的返回类型有关。
  • @Carcigenicate 更新了示例代码,希望这能解决所有问题!
  • 拥有一个并非来自承诺的.then 方法似乎有点奇怪。

标签: javascript asynchronous typescript promise


【解决方案1】:

Promise 被定义为具有称为.then 的方法的对象。例如,它们没有定义为“require('bluebird/promise') 返回的模块”。

这很重要的部分原因是,当 Promise 库解析一个 Promise 时,如果该结果本身就是一个 Promise,它并不意味着在对 .then 的调用中提供最终结果。例如:

function myFn() {
  // doPromise1 will eventually give us `1`.
  return doPromise1().then(x => {
    // doPromise2 will eventually give us `2`.
    return doPromise2();
  });
}

调用此函数并在结果上调用.then 不会返回我在doPromise2() 中得到的承诺。它会返回2 - 所以它会等到两个promise都完成,然后给出最终值。

这与我在then 中返回3 不同。它将看到结果不是一个承诺,并将其作为最终值提供。然而,问题的症结在于它如何知道这不是一个承诺。它不进行类型检查,例如 if p instanceof Promise,因为各种库中有太多的 Promise 定义和 polyfill,它们旨在协同工作。相反,他们会检查一些应如下所示的通用内容:if (typeof p.then === 'function')

该检查正在为您的班级返回 true,这会导致它认为您的值本身就是一个 Promise。它运行它,希望取回另一个 Promise 对象,但得到一个数字并失败。

【讨论】:

    【解决方案2】:

    您的then 方法与 Promise API 相关 - 从 JavaScript 鸭式的角度来看,您的类是 thenable 参见 the spec,特别是 this step

    ...
    Let then be Get(resolution, "then").
    ...
    

    如果您的承诺解析为具有then 函数的对象,那么它具有特殊含义 - 它是thenable。您不能生成具有 then 函数的结果对象,并且它们没有被 Promise 解析算法处理。

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 2019-12-01
      • 2021-04-10
      • 2019-12-14
      • 2020-06-19
      • 1970-01-01
      • 2019-04-25
      • 2019-07-27
      相关资源
      最近更新 更多