扩展Promise并更改Then签名

时间:2018-12-21 10:46:48

标签: javascript promise es6-promise

我想扩展Promise并更改then签名,以便其回调接收两个值。我尝试了不同的方法,其中两种方法已记录并经过测试here。不幸的是,我遇到各种错误,或者结果类的行为不像Promise。

方法1:Wrapping a native Promise

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);
  }
}

方法2:Extending native Promises

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));
  }
}

有人对我做错了什么建议吗?随时在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);
}

ADDITIONAL_DATA 只是一个用于模拟回调中第二个值的字符串。还提取了它以便在所有版本和测试中保持一致。

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

根据解决方案出现的错误

  • catch无法访问
  • 很多UnhandledPromiseRejectionWarning:警告,因为错误/拒绝没有正确传播。
  • 错误/拒绝抛出得太早了,甚至没有达到我的测试套件中的rejects检查

2 个答案:

答案 0 :(得分:2)

我不太了解为什么要使用工厂方法,而不是直接使用构造函数。

你的意思是这样吗?

class MyExtendedPromise extends Promise {

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

  then(callback, test) {
    console.log('passed new parameter in then:', test);
    console.log('additional data:', this.data);
    return super.then(data => callback(data, test));
  }
}

new MyExtendedPromise((resolve, reject) => {
	setTimeout(() => resolve(true), 2000);
}, 'other additional data').then(data => console.log('my then', data), 'hello world');

答案 1 :(得分:2)

您遇到了问题(尤其是未处理的拒绝问题),因为您没有正确实现import 'raw-loader!css-loader!@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.base-theme.react.css'; import 'raw-loader!css-loader!@fonticonpicker/react-fonticonpicker/dist/fonticonpicker.material-theme.react.css'; 接口。请记住,then只是.catch(onRejected)的别名,then with two parameters是实际的core method of every promise

您始终无视第二个参数,因此没有任何拒绝得到处理。你需要写

.then(undefined, onRejected)