TypeScript / JavaScript:如何使用装饰器模式包装 Promise 对象

TypeScript / JavaScript: How to wrap a Promise object using decorator pattern

我正在尝试用 decorator pattern 包装 TypeScript (JavaScript) Promise 对象,因为我需要在 Promise 的 thencatch 中添加额外的逻辑方法(此处未显示)。

到目前为止,它看起来像这样:

export class Decorator {
    protected _promise: Promise<any>;

    constructor(promise: Promise<any>) {
        this._promise = promise;
    }

    then(onFulfilled: any, onRejected: any): Promise<any> {
        return this._promise.then(r => onFulfilled(r), r => onRejected(r))
    };

    catch(onRejected: any): Promise<any> {
        return this._promise.catch(r => onRejected(r));
    }
}

(async () {
    // Note that doSomethingAsynchronously() returns a Promise<void>
    await new Decorator(doSomethingAsynchronously()); // ERROR!!
})();

但是,正如“ERROR!!”所指出的那样上面的评论,我得到这个构建错误:

Type of "await" operand must either be a valid promise or must not contain a callable "then" member.

我已经尝试过扩展 Promise(因此 class 声明将变为 export class Decorator<T> extends Promise<T>),但随后我必须在构造函数中调用 super() 并将其传递给执行程序对象,它显着改变了 Decorator class。我想避免需要一个执行者,并且想简单地将内部承诺传递给构造函数。

如何才能成功等待装饰器 class 的包装承诺?

我真的不确定你想要完成什么,我同意@jfriend00。也许问你真正想解决的问题也许你能得到更好的答案。

无论如何,这里有一种方法可以做你想做的事......不确定这是否是最好的方法......但它有效......

class Decorator {
    protected _promise: Promise<any>;


    constructor(promise: Promise<any>) {
        this._promise = promise;
    }

    getPromise(onFulfilled?: any, onRejected?: any): Promise<any> {
      return this._promise.then(r => {
        console.log('Decorator:onFulfilled');
        onFulfilled(r);
      })
      .catch(r => {
        console.log('Decorator:onRejected');
        onRejected(r);
      })
    }
}

(async () => {
    // Note that doSomethingAsynchronously() returns a Promise<void>
    const doSomethingAsynchronouslyWithSuccess = () => {
      return new Promise<void>((resolve, reject) => {
        setTimeout(() => resolve(), 1000);
      });
    }
    const doSomethingAsynchronouslyWithFail = () => {
      return new Promise<void>((resolve, reject) => {
        setTimeout(() => reject(), 1000);
      });
    }
    await new Decorator(doSomethingAsynchronouslyWithSuccess()).getPromise();
    await new Decorator(doSomethingAsynchronouslyWithFail()).getPromise();
})();