手写 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) })