async / await在一个名为&#34的类方法中;然后"

时间:2016-12-13 18:42:24

标签: javascript asynchronous typescript promise

我创建了一个有"然后"方法。这个类与Promise类型无关; "然后"方法有不同的目的,并没有回报承诺。我试图在Typescript 2.1.4中编写async / await函数,等待并返回此类的实例,但VS Code中的Typescript服务器给了我错误。如果我将方法重命名为"然后"以外的其他内容,则错误消失。

包含错误的示例代码:

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

有人可以解释为什么将promises用于具有自己的&#34;然后&#34;方法是不允许的,还是解决方法?

2 个答案:

答案 0 :(得分:3)

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 - 所以它将等到两个promises完成,并给出最终值。

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

该检查会为您的班级返回true,这会让您认为您的价值是承诺本身。它运行它,希望得到另一个promise对象,但得到一个数字并失败。

答案 1 :(得分:3)

您的then方法 与Promise API相关 - 从JavaScript端口类型的角度来看,您的班级是thenable,请参见the spec,具体为{ {3}}

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

如果您的承诺解析为具有then函数的对象,则它具有特殊含义 - 它是thenable。您不能生成具有then函数的结果对象,也不能通过Promise解析算法处理它们。