参考资料:
- Promises/A+规范(规范只规定了Promise.then的实现规范)
- 规范中文版(仅参考)
- 工业聚:100 行代码实现 Promises/A+ 规范(Good)
- 剖析Promise内部结构,实现完整的Promise类(Good)
- 最简实现Promise,支持异步链式调用(20行)(就看看吧)
- 阮一峰 - ES6 Promise对象
总结:
- 如何对全局变量的判断;
- 实现Promise A/+,并能通过测试;
- ES6 Promise对象中的其它方法的实现,对Promise对象理解更深一层;
- 学会了如何查看其它源代码,并进行学习;
文件:
Promise/A+测试插件:
/**
* 以下代码是配合promise测试插件promises-aplus-tests
* 1. 终端:npm i promises-aplus-tests -g
* 2. promises-aplus-tests promise_A+.js
*/
MyPromise.deferred = MyPromise.defer = function () {
var dfd = {};
dfd.promise = new MyPromise(function (resolve, reject) {
dfd.resolve = resolve;
dfd.reject = reject;
});
return dfd;
};
try {
module.exports = MyPromise;
} catch (e) {}
catch/finally/all等方法的实现:full_promise.js
研究promise-polyfill源码:promise-polyfill.7z
- 入口文件polyfill.js:主要是平台环境的全局变量判断,若存在平台自身的Promise,则用平台自身的Promise,否则挂载到平台Promise变量上;
- index.js文件:
- 实现了ES6 的Promise对象,其中Promise.then符合Promise/A+规范;
- 对Promise.resolve/reject/all/race/allSettled、Promise.prototype.catch/finally方法进行了实现;
- 异步调用的实现采用了setImmediate/setTimeout;
- 状态转变为reject时的错误显示;
待看:
Promise A+规范中实现的Promise.then等方法,都用到了setTimeout,属于宏任务。因此在HTML中,并不能完全代替原生Promise方法,因为原生Promise.resolve().then(callback),其回调函数是在微任务中执行的。
扩展阅读:为什么不依赖微任务模拟出的 Promise,也能符合 Promises/A+中提到:
第二个问题:微任务跟 Promise,是否并不必有强绑定的关系? 本来就不是绑定的。如何调度的细节,不仅超出Promise/A+,甚至超出了ECMAScript标准的范畴,应由具体的host(如浏览器、Node、Deno、Fib.js等)决定。JS语言标准只规定抽象行为和一些 host hook。在具体的host里——比如浏览器中,你必须将Promise映射到由html标准定义的调度机制上,那么就有微任务和宏任务的差别,所以要么映射到微任务要么映射到宏任务。Node的调度机制并不存在html那样的标准,但所设计的机制是类似的。从各个方面考虑,Promise应该是具有更高优先级的,所以映射到微任务或类似的机制是更合适的。