【发布时间】:2021-09-26 15:25:09
【问题描述】:
我有一系列方法(有些是异步的,有些不是),我想使用bluebird.each 来按顺序处理。这是一个简单的例子:
import bluebird from 'bluebird';
const delay = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
class Template {
propertyA!: number;
propertyB!: number;
constructor() {}
async methodA() {
this.propertyA = 10;
console.log({ thisArgInA: this, propertyA: this.propertyA });
await delay(500);
return this.propertyA;
}
methodB() {
this.propertyB = this.propertyA * 100;
console.log({ thisArgInB: this, propertyB: this.propertyB });
return this.propertyB;
}
}
const instance = new Template();
const sequence = [instance.methodA, instance.methodB];
(async function main() {
await bluebird.each(sequence, (fn) => {
const result = fn.call(instance);
console.log({ result });
});
})();
这会产生这个我不明白的错误:
index.ts:27:20 - error TS2684: The 'this' context of type '(() => Promise<number>) | (() => number)' is not assignable to method's 'this' of type '(this: Template) => Promise<number>'.
Type '() => number' is not assignable to type '(this: Template) => Promise<number>'.
Type 'number' is not assignable to type 'Promise<number>'.
27 const result = fn.call(instance);
我想可能是因为bluebird.each 接受解析为编译器无法协调的值的值或承诺,但我想到的唯一解决方案是强类型返回值”
async methodA: Promise<number> { /*...*/ }
methodB: number { /*...*/ }
但这并没有改变任何东西。我还注意到以下几点:
- 我必须在这里提供上下文,因为调用
each回调中的函数会失去与Template的连接,因为this - 当
methodA同步时(去掉async关键字,去掉delay(),直接返回this.propertyA,就可以了。 - 当我删除
return语句时,一切正常。 - 当我将
fn.call(instance)更改为fn.bind(instance)()时,它工作正常
我怎样才能满足编译器的要求,让它知道如何使用提供的上下文调用这些函数。
有没有更简单的方法可以按顺序调用这些方法,从而保持它们与this 的连接?
【问题讨论】:
-
问题:你为什么要使用蓝鸟?当 Promises 还不是真实的东西时,它是有道理的,但 the
PromiseAPI 多年来一直是规范的一部分。只需使用它,然后从您的代码库中删除旧依赖项?特别是考虑到async使函数返回标准 Promise,而无需显式编写 Promise 代码。然后您可以使用await处理它就像 您正在编写同步代码,而不需要promisethen().catch()语法。 -
我无法在您提供的 StackBlitz 上重现该问题。运行
tsc不会输出任何错误。 -
@Mike'Pomax'Kamermans 所以只删除 bluebird 并在 for-of 循环中处理
sequence中的函数会是更好的解决方案吗? -
@Bergi 我认为你必须运行
npx ts-node index.ts。我不确定您是否可以在该环境中进行像 tsc 这样的全局安装。 -
在 typescript 操场上没有蓝鸟的情况下可以重现错误
标签: javascript typescript async-await this bluebird