MyPromise.js
// 定义常量是为了复用且代码有提示const PENDING = 'pending' // 等待const FULFILLED = 'fulfilled' // 成功const REJECTED = 'rejected' // 失败// 定义一个构造函数class MyPromise { constructor(exector){ // 捕获执行器的错误 try { // exector是一个执行器,立即执行,并传入resolve和reject方法 exector(this.resolve, this.reject) } catch (error) { this.reject(error) } } // 初始状态 status = PENDING // 成功的值 value = undefined // 失败的理由 reason = undefined // 定义成功回调参数 successCallback = [] // 定义失败回调参数 failCallback = [] // 定义数组的原因 // .then方法可以被多次调用, 每次存储的内容要互不影响 // 普通函数this指向的是window或者undefined // 用箭头函数就可以让this指向当前实例对象 resolve = value => { // 判断状态是不是等待,阻止向下执行 if (this.status !== PENDING) return; // 设置状态为成功 this.status = FULFILLED // 保存成功的值 this.value = value // 成功回调存在就调用 // this.successCallback&&this.successCallback(value) // 为了then的多次调用,回调参数保存要求互不影响改进 // shift方法是在数组中删除值,返回被删除的项,每执行一个就删除一个,最终变为0 while(this.successCallback.length) this.successCallback.shift()() } reject = reason => { // 判断状态是不是等待,阻止向下执行 if (this.status !== PENDING) return; // 设置状态为失败 this.status = REJECTED // 保存失败的值 this.reason = reason // 失败回调存在就调用 // this.failCallback&&this.failCallback(reason) // 为了then的多次调用,回调参数保存要求互不影响改进 // shift方法是在数组中删除值,返回被删除的项,每执行一个就删除一个,最终变为0 while(this.failCallback.length) this.failCallback.shift()() } then(successCallback, failCallback) { // 将then参数变成可选参数 successCallback = successCallback ? successCallback : value => value; failCallback = failCallback ? failCallback : reason => { throw reason } // 为了实现then的链式调用, 需要返回一个promise对象 let promise2 = new MyPromise((resolve, reject) => { // 判断状态 if (this.status === FULFILLED) { // successcallback(this.value) // 使用setTimeout把代码变成异步代码,才能拿到promise2, 去处理then返回自身对象嵌套的问题. setTimeout(() => { // 捕获成功回调方法的错误 try { // 成功调用成功回调,并把值返回 let x = successCallback(this.value) // 把返回值传递给下一个then方法 resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) } else if (this.status === REJECTED) { // 失败调用失败回调,并把原因返回 // failCallback(this.reason) setTimeout(() => { // 捕获成功回调方法的错误 try { // 成功调用成功回调,并把值返回 let x = failCallback(this.reason) // 把返回值传递给下一个then方法 resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) } else { // 等待状态中 // 不知道成功还是失败,所以先把回调参数存起来, 等状态确定再调用 this.successCallback.push(() => { setTimeout(() => { try { let x = successCallback(this.value) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) }) this.failCallback.push(() => { setTimeout(() => { try { let x = failCallback(this.reason) resolvePromise(promise2, x, resolve, reject) } catch (error) { reject(error) } }, 0) }); } }) return promise2 } finally(callback) { return this.then(value => { // callback(); // return value // 利用resolve的等待异步完成功能, 实现finally的return异步等待功能 return MyPromise.resolve(callback()).then(() => value) }, reason => { // callback() // throw reason return MyPromise.resolve(callback()).then(() => { throw reason }) }) } catch(failCallback) { return this.then(undefined, failCallback) } static all(array) { let result = []; let index = 0; return new MyPromise((resolve, reject) => { function addData(key, value) { result[key] = value index++; if (index === array.length) { resolve(result) } } for(let i = 0; i < array.length; i++) { let current = array[i] if (current instanceof MyPromise) { current.then(value => addData(i, array[i]), reason => reject(reason)) } else { addData(i, array[i]) } } }) } static resolve(value) { if (value instanceof MyPromise) return value return new MyPromise(resolve => resolve(value)) }}// 返回普通值和promise对象处理// 普通值 => 直接传递给下一个then// promise对象 先判断promise的返回值 // value => resolve reason => rejectfunction resolvePromise(promise2, x, resolve, reject) { // 判断then方法返回的是不是自己的promise, 是则会产生循环嵌套, 阻止程序运行, 报错 if (promise2 === x) { return reject(new TypeError('Chaining cycle detected for promise #<Promise>')) } if (x instanceof MyPromise) { // promise对象 // x.then(value => resolve(value), reason => reject(reason)) x.then(resolve, reject) } else { // 普通值 resolve(x) }}module.exports = MyPromise