前言
本文仅作为个人记录,文中可能存在不严谨的地方。
要了解更多可以看下这两篇文章:
正文
Promise/A+ 的标准有哪些?
- 只有一个 then 方法,没有 catch、race、all 等方法。
- then 返回一个新的 Promise。
- 不同的 Promise 的实现需要相互调用。
- Promise 的状态有 pending、fullfilled、rejected 三种。初始状态是 pending ,可以由 pending 转化为 fullfilled 或者 rejected。一旦状态确定之后,不能再被改变。
- 更具体的官方标准,看这里。
下面上代码
function MyPromise(executor) { const _this = this; // 状态 _this.status = 'pending'; // resolve 值 _this.value = null; // reject 原因 _this.reason = null; // resolve、reject 函数 _this.onFullfilled = []; _this.onRejected = []; function resolve(value) { if (value instanceof MyPromise) { return value.then(resolve, reject); } // 其实这里采用 setTimeout 方式实现异步执行 onFullfilled/onRejected 不太符合 Event Loop 机制。下面 reject 同理。 setTimeout(() => { // 只有状态为 pending 才能被改变 if (_this.status == 'pending') { _this.value = value; _this.status = 'resolved'; _this.onFullfilled.forEach(currentValue => currentValue(value)); } }, 0); } function reject(reason) { setTimeout(() => { // 只有状态为 pending 才能被改变 if (_this.status == 'pending') { _this.reason = reason; _this.status = 'rejected'; _this.onRejected.forEach(currentValue => currentValue(reason)); } }, 0); } // 注意:若执行过程出现异常,则捕获异常并执行 reject 函数。 try { executor(resolve, reject) } catch (e) { reject(e); } } function resolvePromise(promise2, x, resolve, reject) { let then; let thenCallorThrow = false; if (promise2 === x) { return reject(new TypeError('same Promise!')) } if (x instanceof MyPromise) { if (x.status === 'pending') { x.then(value => { resolvePromise(promise2, value, resolve, reject) }, reject) } else { x.then(resolve, reject) } return } if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) { try { then = x.then; if (typeof then === 'function') { then.call(x, res => { if (thenCallorThrow) return; thenCallorThrow = true; return resolvePromise(promise2, res, resolve, reject); }, err => { if (thenCallorThrow) return; thenCallorThrow = true; return reject(err) }) } else { resolve(x); } } catch (e) { if (thenCallorThrow) return; thenCallorThrow = true; return reject(e) } } else { return resolve(x) } } MyPromise.prototype.then = function (onFullfilled, onRejected) { const _this = this; let promise2; // promise.then() 返回一个 promise 对象 // Promise 值的穿透处理: // 场景如: new Promise(resolve => resolve('abc')).then().catch().then(res => {console.log('print abc')}) onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : val => val; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }; switch (_this.status) { case 'pending': promise2 = new MyPromise((resolve, reject) => { _this.onFullfilled.push(value => { try { let x = onFullfilled(value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e) } }); _this.onRejected.push(reason => { try { let x = onRejected(reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e) } }); }) case 'resolved': promise2 = new MyPromise((resolve, reject) => { setTimeout(() => { try { let x = onFullfilled(_this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e) } }); }) case 'rejected': promise2 = new MyPromise((resolve, reject) => { setTimeout(() => { try { let x = onRejected(_this.reason); resolvePromise(promise2, x, resolve, reject) } catch (e) { reject(e) } }); }) default: break; } return promise2; } // Promise 标准里面没有 catch、race、all 等方法,只有一个 then 方法 MyPromise.prototype.catch = function (onRejected) { return this.then(null, onRejected) } new MyPromise((resolve, reject) => { resolve('right'); }).then(res => { console.log(res) }, err => { console.warn(err) })