手写 Promise 的实现
从实现原理的角度分析 Promise 是什么
从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。ES6 原生提供了Promise对象。
Promise内部有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,并且一旦状态改变,就不会再变,任何时候都可以得到这个结果。
Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。
有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数。
实现步骤
- 创建一个 Promise函数,内部声明三个变量:- PromiseState:表示当前- Promise的状态
- PromiseResult:表示当前- Promise的执行结果
- callBack: 表示当前- Promise状态更改后要执行的回调函数数组
- 状态根据传入的参数函数执行决定,如果函数的执行过程中出现了报错,则通过try/catch捕获到后,调用reject函数,将当前Promise的状态置为 rejected,否则函数的状态根据参数函数excutor的执行结果决定,如果excutor返回不为Promise对象的实例,则直接调用resolve将当前Promise实例的状态置为fullfilled,如果excutor返回的是Promise对象的实例,则根据promise.then( v => { resolve(v);}, r => {reject(r);})的执行结果判断当前Promise的执行状态
 function Promise(excutor) {this.PromiseState = 'pending'this.PromiseResult = nullthis.callBack = []const self = thistry{excutor(resolve, reject)} catch(e) {reject(e)}function resolve(value) {if(self.PromiseState !== 'pending') returnself.PromiseState = 'fullfilled'self.PromiseResult = valueexcuteCallback(self)}function reject(reason) {if(self.PromiseState !== 'pending') returnself.PromiseState = 'rejected'self.PromiseResult = reasonexcuteCallback(self)} } function excuteCallback(self) {self.callBack.forEach(item => {if(self.PromiseState === 'fullfilled') {item.resolveCallback&&item.resolveCallback(self.PromiseResult)}else if(self.PromiseState === 'rejected'){item.rejectCallback && item.rejectCallback(self.PromiseResult)}}); }
- 实现then函数,then函数接收两个回调函数,then函数返回一个新的Promise实例对象- 第一个函数参数 onResolved:当前Promise实例状态为fullfilled时执行
- 第二个函数参数 onRejected:当前Promise实例状态为rejected时执行
- then函数返回的- Promise实例对象的状态根据参数函数的执行结果决定,通过- try{}catch(){}捕获错误- 如果未有任何报错,则调用resolve并且将onResolved执行结果作为resolve函数的参数,更改状态为fullfilled,
- 若捕获到错误,则执行reject并且将onRejected执行结果作为reject函数的参数,更改状态为rejected。
- 如果 onResolved或onRejected函数的执行结果返回的是一个Promise实例对象,则根据result.then( v => { resolve(v);}, r => {reject(r);})的执行结果判断当前Promise的执行状态
 
- 如果未有任何报错,则调用
 Promise.prototype.then = function(onResolved, onRejected) {return new Promise((resolve,reject) => {if(this.PromiseState === 'fullfilled') {const thenResult = onResolved(this.PromiseResult)resolve(thenResult)} else if(this.PromiseState === 'rejected') {const rejectResult = onRejected(this.PromiseResult)resolve(rejectResult)} else {this.callBack.push({resolveCallback: (result)=>{resolve(onResolved(result))},rejectCallback: (reason) => {resolve(onRejected(reason))}})} }) }
- 第一个函数参数 
- 实现 catch函数- catch函数其实是- then函数的变形写法,通过将第一个参数置为- undefined表示只捕获错误问题,不处理成功时候的回调
 Promise.prototype.catch = function(onRejected) {return this.then(undefined, onRejected) }
- 实现 all函数- all函数接收一个- Promise数组,并且返回一个新的- Promise实例
- 如果Promise数组中有一个状态变为rejected,返回的实例的实例状态就是rejected,实例结果为第一个执行状态为rejected的执行结果
- 等待所有的Promise数组都执行完并且更改状态之后再更改返回的Promise实例的状态,并且每个Promise实例的状态是fullfilled,返回的实例的状态就是fullfilled,结果为这些Promise实例执行的结果数组
 Promise.all = function(promises) {return new Promise((resolve, reject) => {let count = 0, arr = []for(let i=0; i<promises.lenghth; i++) {promises[i].then(value=>{count++arr[i] = valueif(count === promises.lenghth) {resolve(arr)}}, reason=>{reject(reason)})}}) }
- 实现 race函数- race函数接收一个- Promise数组,并返回一个新的- Promise实例,返回的实例状态为第一个- Promise状态改变的状态,返回的值也是第一个- Promise状态改变的值
 Promise.race = function(promises) {return new Promise((resolve, reject) => {for(let i=0; i<promises.lenghth;i++) {promises[i].then(value => {resolve(value)}, reason => {reject(reason)})}}) }
- 验证自定义 Promise 函数let p = new Promise((resolve, reject)=> {setTimeout(()=>{resolve(112)},100) }) p.then(value=>{console.log(11111,value)return 123123123 },reason=>{console.log(10000, reason) }).then(value=>{console.log(211111,value) },reason=>{console.log(210000, reason) })