手写符合Promise/A+规范的Promise
const PENDING = "pending"; const RESOLVED = "resolved"; const REJECTED = "rejected"; function MyPromise(fn){ const that = this; that.state = PENDING; that.value = null; that.resolvedCallbacks = []; that.rejectedCallbacks = []; function resolve(value){ // 判断传入的值是否为 Promise 类型 if( value instanceof MyPromise){ return value.then(resolve, reject) } // 为了保证函数的执行顺序,需要将两个函数体代码使用 setTimeout 包裹起来 setTimeout(()=>{ // 只有等待状态才可以改变状态 if(that.state == PENDING){ // 将当前状态更改为对应状态,并且将传入的值赋值给 value that.state = RESOLVED; that.value = value; // 遍历回调数组并执行 that.resolvedCallbacks.map(cb => cb(that.value)); } },0) } function reject(value){ setTimeout(()=>{ if(that.state == PENDING){ that.state == REJECTED; that.value = value; that.rejectedCallbacks.map( cb => cb(that.value)); } }) } try { fn(resolve, reject) } catch (e) { reject(e) } } MyPromise.prototype.then = function(onFulfilled, onRejected){ const that = this; // 判断两个参数是否为函数类型, 这两个参数是可选参数 // 当参数不是函数类型时,需要创建一个函数赋值给对应的参数,同时也实现了透传 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v; onRejected = typeof onRejected === 'function' ? onRejected : r => {throw r}; if(that.state === PENDING){ // 返回了一个新的 Promise 对象,并在 Promise 中传入了一个函数 // 规范规定,执行 onFulfilled 或者 onRejected 函数时会返回一个 x,并且执行 Promise 解决过程,这是为了不同的 Promise 都可以兼容使用,比如 JQuery 的 Promise 能兼容 ES6 的 Promise return (promise2 = new MyPromise((resolve, reject)=>{ that.resolvedCallbacks.push(()=>{ try { const x = onFulfilled(that.value) resolutionProcedure(promise2, x, resolve, reject) }catch (r) { reject(r) } }); that.rejectedCallbacks.push(()=>{ try { const x = onRejected(that.value) resolutionProcedure(promise2, x, resolve, reject) } catch (r) { reject(r) } }); })) } if(that.state === RESOLVED){ return (promise2 = new MyPromise((resolve, reject)=>{ setTimeout(()=>{ try { const x = onFulfilled(that.value) resolutionProcedure(promise2, x, resolve, reject) } catch (reason) { reject(r) } }) })) } if(that.state === REJECTED){ return (promise2 = new MyPromise((resolve, reject)=>{ try { const x = onRejected(that.value); resolutionProcedure(promise2, x, resolve, reject) }catch(r){ reject(r) } })) } function resolutionProcedure(promise2, x, resolve, reject) { if (promise2 === x) { return reject(new TypeError('Error')) } if (x instanceof MyPromise) { x.then(function(value) { resolutionProcedure(promise2, value, resolve, reject) }, reject) } // 创建一个变量 用于判断是否已经调用过函数 // let called = false; // if (x !== null && (typeof x === 'object' || typeof x === 'function')) { // try { // let then = x.then // if (typeof then === 'function') { // then.call( // x, // y => { // if (called) return // called = true // resolutionProcedure(promise2, y, resolve, reject) // }, // e => { // if (called) return // called = true // reject(e) // } // ) // } else { // resolve(x) // } // } catch (e) { // if (called) return // called = true // reject(e) // } // } else { // resolve(x) // } } } // 创建一个实例 new MyPromise((resolve, reject) => { setTimeout(() => { resolve(1) }, 0) }).then(value => { console.log(value) })