Deferred 扩展了 Promise

Deferred that extends Promise

如何实现扩展 Promise 的 Deferred Promise?在需要典型 Promise 的地方扩展 Promise 以实现类型安全使用很重要。

实施后

export class Deferred<T> extends Promise<T> {                                   
  public _resolveSelf;
  public _rejectSelf;                                                           
  constructor() {
    super(
      (resolve, reject) =>
      {
        this._resolveSelf = resolve
        this._rejectSelf = reject
      }
    )
  }                                                                             
  public resolve(val:T) { this._resolveSelf(val) }
  public reject(reason:any) { this._rejectSelf(reason) }                        
}

抛出 TypeError: _this is undefined

this Typescript playground中,可以看出编出来的javascript很搞笑。在第 15 行,在 _this 的声明期间已经分配了它的属性。

export class Deferred<T> implements Promise<T> {

  private _resolveSelf;
  private _rejectSelf;
  private promise: Promise<T>

  constructor() {
    this.promise = new Promise( (resolve, reject) =>
      {
        this._resolveSelf = resolve
        this._rejectSelf = reject

      }
    )
  }

  public then<TResult1 = T, TResult2 = never>(
    onfulfilled?: ((value: T) =>
      TResult1 | PromiseLike<TResult1>) | undefined | null,
    onrejected?: ((reason: any) =>
      TResult2 | PromiseLike<TResult2>) | undefined | null
    ): Promise<TResult1 | TResult2> {
      return this.promise.then(onfulfilled, onrejected)
    }

  public catch<TResult = never>(
    onrejected?: ((reason: any) =>
      TResult | PromiseLike<TResult>) | undefined | null
    ): Promise<T | TResult> {
      return this.promise.catch(onrejected)
    }

  public resolve(val:T) { this._resolveSelf(val) }
  public reject(reason:any) { this._rejectSelf(reason) }

  [Symbol.toStringTag]: 'Promise'

}

thencatch 的方法签名从 Typescript's Promise interface 复制粘贴并进行了美化清理。 [Symbol.toStringTag] 行也是 Typescript 将其视为 Promise 所必需的,尽管您只能在编译时发现它。

How to implement a Deferred promise that extends Promise?

最好不要。绝对有.

即便如此,延迟 是一个 承诺是一个坏主意,您应该分离功能:

function defer() {
    var deferred = {};
    deferred.promise = new Promise(resolve => {
        deferred.resolve = resolve;
    });
    return deferred;
}

One can see that the compiled javascript is funny. In line 15, during declaration of _this already its properties are being assigned.

是的,这就是 super 的工作原理:在父构造函数调用返回并初始化它之前,您不能使用 this。然而,promise 执行器回调在此之前被调用。

你必须写

export class Deferred<T> extends Promise<T> {
  public resolve: T=>void;
  public reject: any=>void;
  constructor() {
    var resolveSelf, rejectSelf
    super((resolve, reject) => {
      resolveSelf = resolve
      _rejectSelf = reject
    })
    this.resolve = resolveSelf;
    this.reject = rejectSelf;
  }
}