扩展`Promise`并改变`then`签名

Ken*_*avR 6 javascript promise es6-promise

我想扩展Promise和更改then签名,以便其回调接收两个值.我尝试了不同的方法,其中两个在此处记录和测试.可悲的是,我得到了各种错误,或者由此产生的类不像Promise.

方法1:包装本机承诺

export class MyWrappedPromise {
  constructor(data) {
    this.data = data;
    this.promise = new Promise(evaluate.bind(data));
  }

  then(callback) {
    this.promise.then(() => callback(this.data, ADDITIONAL_DATA));
  }

  catch(callback) {
    this.promise.catch(callback);
  }
}
Run Code Online (Sandbox Code Playgroud)

方法2:扩展本机承诺

export class MyExtendedPromise extends Promise {

  constructor(executor, data) {
    super(executor);
    this.data = data;
  }

  static create(data) {
      return new MyExtendedPromise(evaluate.bind(data), data);
  }

  then(callback) {
    return super.then(() => callback(this.data, ADDITIONAL_DATA));
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有人对我做错了什么有任何建议?随意在GitHub上创建PR.

谢谢

-------------------编辑---------------------

一些额外的代码和信息使得上面的代码更容易理解,而无需查看Github上的代码和测试.

evaluate只是Promise执行者函数.我把它解压出来,这样我就可以在所有的实现和测试中保持一致.它可能看起来很复杂,但它的结构是模拟我的"真实"项目.

export function evaluate(resolve, reject) {
  const data = this;
  function getPromise(data) {
    return !!data ? Promise.resolve(data) : Promise.reject(new Error("Error"));
  }

  getPromise(data)
    .then(resolve)
    .catch(reject);
}
Run Code Online (Sandbox Code Playgroud)

ADDITIONAL_DATA只是一个字符串,用于模拟回调中的第二个值.它也被提取为在所有版本和测试中保持一致.

-------------------编辑2 ---------------------

根据解决方案出现的错误

  • catch 不可访问
  • 很多UnhandledPromiseRejectionWarning:警告,因为错误/拒绝没有正确传播.
  • 错误/拒绝被过早抛出,甚至无法到达rejects我的测试套件中的支票

Ber*_*rgi 2

您遇到问题(尤其是未处理的拒绝)是因为您没有then正确实现接口。请记住,这.catch(onRejected)只是 的别名.then(undefined, onRejected)then带有两个参数的是每个 Promise 的实际核心方法。

你总是忽略第二个论点,所以没有处理任何拒绝。你需要写

then(onFulfilled, onRejected) {
  return super.then(res => onFulfilled(res, this.ADDITIONAL_DATA), onRejected);
  // or `this.promise.then` instead of `super.then`
}
Run Code Online (Sandbox Code Playgroud)