根据PromiseA+规范实现Promise
Posted lyralee
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了根据PromiseA+规范实现Promise相关的知识,希望对你有一定的参考价值。
1. Promise源码
resolvePromise函数
function resolvePromise(promise, x, resolve, reject) { if(x === promise) { return reject(new TypeError(`Chaining cycle detected for promise #<Promise>`)); } /** * 判断是否是promise有三个条件 * 1.是对象,且不是null * 2.是函数 * 3.满足1,2其中一个的基础上,有then属性,且是个函数 */ if((typeof x === ‘object‘ && x !== null) || typeof x === ‘function‘) { // 确保即使x是他人自定义的promise对象时,状态改变也只执行一次 let called; try { // 如果then属性通过getter定义 let then = x.then; if (typeof then === ‘function‘) {// 是promise // then方法调用时绑定this,否则可能会导致this指向变更; 第二个参数成功回调 then.call(x, y => { if(called) return; called = true; // y仍然可能是promise resolvePromise(promise, y, resolve, reject); }, r => {//失败回调 if(called) return; called = true; reject(r); }) } else { resolve(x); } } catch (e) { if(called) return; called = true; reject(e); } } else { // 普通值 resolve(x); } } module.exports = resolvePromise;
Promise源码
/** * 1. Promise实例化时有个执行器函数,会立即执行 * 2. 执行器有两个方法,第一个是resolve, 第二个是reject * 3. promise实例有三种状态,pending, fulfilled, rejected * 默认是pending, 调用resolve后变为fulfilled; 调用reject后变为rejected * 4. 状态不可逆, 只能pending->fulfilled, 或者pending -> rejected * 5. 每个promise实例都有个then方法,then方法有两个参数, * 第一个是成功回调onFulfilled,第二个是失败回调onRejected * 6. 执行器的resolve函数会触发成功回调onFulfilled, * 执行器的reject函数或者throw触发失败回调onRejected * 7. then方法返回的是一个promise对象。 * */ const PENDING = ‘PENDING‘; const FULFILLED = ‘FULFILLED‘; const REJECTED = ‘REJECTED‘; const resolvePromise = require(‘./resolvePromise‘); class Promise { constructor(executor) { this.value; this.reason; this.status = PENDING; this.onResolvedCallbacks=[]; // then成功回调队列 this.onRejectedCallbacks=[]; // then失败回调队列 let resolve = (value) => { if(this.status === PENDING) { this.status = FULFILLED; this.value = value; this.onResolvedCallbacks.forEach(fn => fn()); } } let reject = (reason) => { if(this.status === PENDING) { this.status = REJECTED; this.reason = reason; this.onRejectedCallbacks.forEach(fn => fn()) } } try{ executor(resolve, reject); } catch(err) { reject(err) } } then(onFulfilled, onRejected) {// 两个回调函数,都是可选参数 // 当参数不是回调函数或者省略时,赋予默认回调函数,将值向后传递 onFulfilled = typeof onFulfilled === ‘function‘ ? onFulfilled : val => val; onRejected = typeof onRejected === ‘function‘ ? onRejected : e => {throw e}; // 返回promise可以实现链式调用 const promise = new Promise((resolve, reject) => { if(this.status === FULFILLED) { //微任务,等到new实例完成之后,获取返回的promise;否则promise未定义 process.nextTick(() => { try { let x = onFulfilled(this.value); // x有可能是promise对象,则需要继续处理,直至返回的是普通数据(非异常和promise) resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e); } }) } if(this.status === REJECTED) { process.nextTick(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e) } }) } if(this.status === PENDING) { this.onResolvedCallbacks.push(() => { process.nextTick(() => { try { let x = onFulfilled(this.value); resolvePromise(promise, x, resolve, reject); } catch (e) { reject(e); } }) }) this.onRejectedCallbacks.push(() => { process.nextTick(() => { try { let x = onRejected(this.reason); resolvePromise(promise, x, resolve, reject); } catch(e) { reject(e); } }) }) } }) return promise; } } module.exports = Promise;
2. 测试是否符合规范
1.全局安装测试命令工具
npm install promises-aplus-tests -g
2. 在代码中添加
// 测试Promise是否符合规范 Promise.deferred = function() { let dfd = {}; dfd.promise = new Promise((resolve, reject) => { dfd.resolve = resolve; dfd.reject = reject; }) return dfd; }
3. 使用命令工具测试
promises-aplus-tests promise.js
以上是关于根据PromiseA+规范实现Promise的主要内容,如果未能解决你的问题,请参考以下文章
Promise的源码实现(完美符合Promise/A+规范)