我创建了一个有"然后"方法。这个类与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;方法是不允许的,还是解决方法?
答案 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解析算法处理它们。