【问题标题】:TypeScript / JavaScript: How to wrap a Promise object using decorator patternTypeScript / JavaScript:如何使用装饰器模式包装 Promise 对象
【发布时间】:2021-08-16 06:28:23
【问题描述】:

我正在尝试使用 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!!
})();

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

“await”操作数的类型必须是有效的承诺,或者不能包含可调用的“then”成员。

我尝试过扩展 Promise(因此类声明将变为 export class Decorator&lt;T&gt; extends Promise&lt;T&gt;),但随后我必须在构造函数中调用 super() 并向其传递一个执行器对象,这会大大改变装饰器类。我想避免需要执行器,并且想简单地将内部承诺传递给构造函数。

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

【问题讨论】:

  • 您真正想解决什么问题?请描述并显示该代码,然后我们可以更好地提供解决实际问题的方法,而不是仅仅尝试评论您选择的特定路径,这可能不是最好的方法。仅供参考,这是一个XY problem,您描述它的方式应该在这里避免。

标签: javascript typescript promise


【解决方案1】:

我真的不确定你想要完成什么,我同意@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();
})();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-23
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 2012-08-27
    • 1970-01-01
    相关资源
    最近更新 更多