在 `enumerator.js#L82` 中拦截 `Promise.resolve` 失败
作者: codeworrior创建于 2018年7月7日更新于 2018年7月7日
在我们使用的测试框架中,Promise.resolve 被拦截(以及其他方法),以实现对未完成的 Promise、定时器、请求等的一些记账。拦截代码的样子如下:
(function() {
const originalResolve = Promise.resolve; // *1*
Promise.resolve = function(value) {
// 将当前调用传播给原始函数,使用相同的上下文和参数
let result = originalResolve.call(this, value); // *2*
// 记账是通过原始调用实现的,这里无关紧要
return result;
};
}());
最近,我们尝试将 **es6-promise** 从 2.3.0 升级到 4.2.4,以利用 `Promise.prototype.finally`。但是,上述拦截代码出现了错误,错误信息为:
> TypeError: Constructor is not a constructor
at resolve$1 (es6-promise.js:231:17)
原因似乎是,es6-promise 当前的 `Promise.resolve` 实现依赖于 `this`(以允许继承),但是 `Enumerator.prototype._eachEntry` 实现忽略了这个事实 [这里](https://GitHub.com/stefanpenner/es6-promise/blob/master/lib/es6-promise/enumerator.js#L63),结合 [第 82 行](https://GitHub.com/stefanpenner/es6-promise/blob/master/lib/es6-promise/enumerator.js#L82) 使用。
引用 #286(IMHO 同样适用于 _resolve_):
> 如果你想要解构所有内容,可以这样做,但必须先绑定。
好吧,我理解这个适用于我们的测试框架(行 *1*)并且绑定 `originalResolve` 可以解决问题。但是我认为,使用当前 `this` 和参数调用 `originalResolve`(行 *2*)也是可行的,而且更加通用。即使有人在 `Promise` 的子类中重用封装的 `Promise.resolve`,也应该能够正常工作。
IMHO,如果 `Enumerator.prototype._eachEntry` 遵循“如果你想要解构 ... 它必须先被绑定”这一规则,或者 [在第 82 行调用 `Constructor.resolve`](https://GitHub.com/stefanpenner/es6-promise/blob/master/lib/es6-promise/enumerator.js#L82) 将是更公平的做法。
你怎么看呢?内容来源: stefanpenner/es6-promise