手写Promise
要看完整代码直接拉到最下方即可
(1).初始结构搭建与resolve,reject结构搭建
//声明构造函数 Promise对象有两个属性一个PromiseState 一个PromiseResult function Promise(executor){ //声明属性 this.PromiseState='pending' this.PromiseResult=null //保存实例对象的this const self=this //在resolve方法中我们要改变Promise对象状态,改变PromiseResult function resolve(data){ self.PromiseState='fulfilled' self.PromiseResult=data } //同理 function rejected(data){ if(self.PromiseState!=='pending') return self.PromiseState='rejected' self.PromiseResult=data } //同步调用[执行器函数] executor(resolve,reject) } //添加then方法 Promise.prototype.then=function(onResolved,onRejected){ }
(2).throw抛出异常改变状态
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this function resolve(data){ self.PromiseState='fulfilled' self.PromiseResult=data } function reject(data){ self.PromiseState='rejected' self.PromiseResult=data } //在执行器函数 throw抛出异常想到用try...catch; try{ executor(resolve,reject) }catch(e){ //修改promise对象的状态为失败 reject(e)//为什么是e不是data了?因为结果值就是抛出的结果值 } } Promise.prototype.then=function(onResolved,onRejected){ }
(3)Promise对象状态只能改变一次以及then方法执行回调
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this function resolve(data){ //判断状态 if(self.PromiseState!=='pending')return self.PromiseState='fulfilled' self.PromiseResult=data } function reject(data){ if(self.PromiseState!=='pending')return self.PromiseState='rejected' self.PromiseResult=data } try{ executor(resolve,reject) }catch(e){ reject(e) } } Promise.prototype.then=function(onResolved,onRejected){ //调用回调函数 if(this.PromiseState==='fulfilled){ //因为这里是实例对象调用的所以直接用this就行 onResolved(this.PromiseResult) } if(this.PromiseState==='rejected'){ onRejected(this.PromiseResult) } }
(4)异步任务回调的执行
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this //声明属性 this.callback={} function resolve(data){ if(self.PromiseState!=='pending')return self.PromiseState='fulfilled' self.PromiseResult=data //调用成功的回调函数 if(self.callback.onResolved){ self.callback.onResolved(data) } } function reject(data){ if(self.PromiseState!=='pending')return self.PromiseState='rejected' self.PromiseResult=data //调用失败的回调 if(self.callback.onRejected){ self.callback.onRejected(data) } } try{ executor(resolve,reject); }catch(e){ resolve(e) } Promise.prototype.then=function(onResolved,onRejected){ if(this.PromiseState==='fulfilled'){ onResolved(this.PromiseResult) } if(this.PromiseState === 'rejected'){ onRejected(this.PromiseResult) } if(this.PromiseState==='pending'){ //保存回调函数 this.callback={ onResolved:onResolved onRejected:onRejected } } }
(5)指定多个回调的实现
function Promise(executor){ this.PromiseState='pending'; this.PromiseResult=null; const self=this; //this.callback={}; //这样保存有个弊端,后面的回调函数会把它覆盖掉 this.callbacks=[] function resolve(data){ if(self.PromiseState!=='pending') return; self.PromiseState='fulfilled'; self.PromiseResult=data; /**if(self.callback.onResolved){ self.callback.onResolved(data); }*/ //遍历 self.callbacks.forEach(item=>{ item.onResolved(data) }) } function reject(data){ if(self.PromiseState!=='pending') return; self.PromiseState='rejected'; self.PromiseResult=data; /**if(self.callback.onRejected){ self.callback.onRejected(data); }*/ self.callbacks.forEach(item=>{ item.onRejected(data) }) } try{ executor(resolve, reject); }catch(e){ reject(e); } } Promise.prototype.then=function(onResolved,onRejected){ if(this.PromiseState==='fulfilled'){ onResolved(this.PromiseResult); } else if(this.PromiseState==='rejected'){ onRejected(this.PromiseResult); } if(this.PromiseState==='pending'){ this.callbacks.push({ onResolved:onResolved, onRejected:onRejected }) } };
(6)同步修改then方法和异步修改then方法 结果返回
这里我一开始犯了个错误,想着在执行器函数中写过try...catch捕获错误了,不用再在then方法中捕获。其实是不对的,因为执行器函数中的try...catch是用来捕获在初始化解析或拒绝状态时可能发生的错误。then方法中的try...catch则是用来捕获onResolved或onRejected回调函数中可能抛出的异常。这些异常通常发生在Promise已经解析或拒绝之后,注册新的回调函数并执行他们。
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this const callbacks=[] function resolve(data){ if(self.PromiseState!='pending) return self.PromiseState='fulfilled' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onResolved(data) }) } function reject(data){ if(self.PromiseState!='pending) self.PromiseState='rejected' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onRejected(data) }) } try{ executor(resolve,reject) }catch(e){ reject(e) } } Promise.prototype.then(onResolved,onRejected){ const self=this //返回一个新的Promise对象 return new Promise((resolve,reject)=>{ if(this.PromiseState==='fulfilled'{ //获取回调函数的执行结果 try{ let result=onResolved(this.PromiseResult) //判断执行结果是否为一个Promise对象 if(result instanceof Promise){ result.then(v=>{ resolve(v) },r=>{ reject(r) }) }else{ //结果对象的状态为成功 resolve(result) } }catch(e){ reject(e) } } if(this.PromiseState==='rejected'{ onRejected(this.PromiseResult) } if(this.PromiseState==='pending'{ this.callbacks.push({ onResolved:function(){ //判断 try{ //执行成功的回调函数 let result=onResolved(self.PromiseResult) if(result instance of Promise){ result.then(v=>{ resolve(v) },r=>{ reject(r) }) }else{ resolve(v) } }catch(e){ reject(e) } }, onRejected:function(){ try{ //执行失败的回调函数 let result = onRejected(self.PromiseResult) if(result instance of Promise){ result.then(v=>{ resolve(v) },r=>{ reject(r) }) }else{ resolve(v) } }catch(e){ reject(e) } } }) } }) }
(7)完善then方法
从上面的代码中看出来,有很多重复的代码,为了简洁,我们将它进行封装
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this const callbacks=[] function resolve(data){ if(self.PromiseState!='pending')return self.PromiseState='fulfilled' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onResolved(data) }) } function reject(data){ if(self.PromiseState!='pending')return self.PromiseState='rejected' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onRejected(data) }) } try{ executor(resolve,reject) }catch(e){ reject(e) } } Promise.prototype.then=function(onResolved,onRejected){ const this=self return new Promise((resolve,reject)=>{ //封装函数 function callback(type){ let result=type(self.PromiseResult) try{ if(result instanceof Promise){ result.then(v=>{ resolve(v) },r=>{ reject(r) }else{ resolve(result) } }catch(e){ reject(e) } } if(this.PromiseState==='fulfilled'){ callback(onResolved) } if(this.PromiseState==='rejected'){ callback(onRejected) } if(this.PromiseState==='pending'){ this.callbacks.push({ onResolved:function(){ callback(onResolved) }, onRejected:function(){ callback(onRejected) } }) } }) }
(8)catch方法的封装我们要实现两个功能:1.catch传统2.值传递;resolve方法的封装
function Promise(executor){ this.PromiseState='pending' this.PromiseResult=null const self=this const callbacks=[] function resolve(data){ if(self.PromiseState!='pending')return self.PromiseState='fulfilled' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onResolved(data) }) } function reject(data){ if(self.PromiseState!='pending')return self.PromiseState='rejected' self.PromiseResult=data self.callbacks.forEach(item=>{ item.onRejected(data) }) } try{ executor(resolve,reject) }catch(e){ reject(e) } } Promise.prototype.then=function(onResolved,onRejected){ const this=self //判断回调函数 if(typeof onRejected !=='function'){ onRejected=reason=>{ throw reason } if(typeof onResolved !=='function'){ onResolved=value=>value } return new Promise((resolve,reject)=>{ function callback(type){ let result=type(self.PromiseResult) try{ if(result instanceof Promise){ result.then(v=>{ resolve(v) },r=>{ reject(r) }else{ resolve(result) } }catch(e){ reject(e) } } if(this.PromiseState==='fulfilled'){ callback(onResolved) } if(this.PromiseState==='rejected'){ callback(onRejected) } if(this.PromiseState==='pending'){ this.callbacks.push({ onResolved:function(){ callback(onResolved) }, onRejected:function(){ callback(onRejected) } }) } }) } //封装catch方法 Promise.prototype.catch=function(onRejected){ return this.then(undefind,onRejected) } //封装resolve方法 Promise.resolve=function(value){ //返回promise对象 return new Promise((resolve,reject)=>{ if(value instanceof Promise){ value.then(v=>{ resolve(v) },r=>{ reject(r) }) }else{ //状态设置成功 resolve(value) } }) } //封装reject方法 Promise.reject=function(reason){ return new Promise((resolve,reject)=>{ reject(reason) }) } //封装all方法 Promise.all=function(promises){ return new Promise((resolve,reject)=>{ let count=0 let arr=[] //遍历 for(let i=0;i<promises.length;i++){ promises[i].then(v=>{ //得知对象状态是成功的 //每个promise对象都成功 count++; //将当前promise对象成功的结果存入数组当中 arr[i]=v //判断 if(count ===promises.length){ resolve(arr) } },r=>{ reject(r) }) } }) } //封装race方法 Promise.race=function(promises){ return new Promises((resolve,reject)=>{ for(int i=0;i<promises.length;i++){ promises[i].then(v=>{ resolve(v) },r=>{ reject(r) }) } }) }
(9)then方法回调的异步执行 完结
//1.声明构造函数 function Promise(excutor){ //5.添加属性 this.PromiseState='pending' this.PromiseResult=null //声明属性 this.callbacks=[] //保存实例对象的this const self=this //4.声明resolve,reject function resolve(data){ //判读状态 if(self.PromiseState!=='pending') return //4.1 修改对象的状态(PromiseState) self.PromiseState='fulfilled' //4.2 设置对象结果值(PromiseResult) self.PromiseResult=data //调用成功的回调函数 ??? setTimeout(()=>{ self.callbacks.forEach(item => { item.onResolved(data) }) }) } function reject(data){ if(self.PromiseState!=='pending') return self.PromiseState='rejected' self.PromiseResult=data setTimeout(()=>{ self.callbacks.forEach(item => { item.onRejected(data) }); }) } try{ //3.执行器函数同步调用 excutor(resolve,reject); }catch(e){ //修改Promise对象状态为[失败] reject(e); } } //2.添加then方法 Promise.prototype.then=function(onResolved,onRejected){ const self=this; //判断回调函数参数 if(typeof onRejected !=='function'){ onRejected=reason=>{ throw reason } } if(typeof onResolved!=='function'){ onResolved=value=>value //简略写法 //value => {return value} } return new Promise((resolve,reject)=>{ //封装函数 function callback(type){ try{ //获取回调函数的执行结果 let result = type(self.PromiseResult) //判断如果回调函数的结果是Promise对象 if(result instanceof Promise){ //如果是Promise对象 result.then(v=>{ resolve(v); },r=>{ reject(r); }) }else{ resolve(result) } }catch(e){ reject(e) } } //调用回调函数 if(this.PromiseState==='fulfilled'){ setTimeout(()=>{ callback(onResolved) }) } if(this.PromiseState==='rejected'){ setTimeout(()=>{ callback(onRejected) }) } //判断pending状态 if(this.PromiseState==='pending'){ //保存回调函数 this.callbacks.push({ onResolved:function(){ callback(onResolved) }, onRejected:function(){ callback(onRejected) } }) } }) } //添加catch方法 Promise.prototype.catch=function(onRejected){ return this.then(undefined,onRejected) } //添加resolve方法 Promise.resolve=function(value){ //返回promise对象 return new Promise((resolve,reject)=>{ if(value instanceof Promise){ value.then(v=>{ resolve(v) },r=>{ reject(r) }) }else{ resolve(value); } }) } //添加reject方法 Promise.reject=function(reason){ return new Promise((resolve,reject)=>{ reject(reason) }) } //添加all方法 Promise.all=function(promises){ //返回结果为Promise对象 return new Promise((resolve,reject)=>{ //声明变量 let count=0; let arr=[]; //遍历 for(let i=0;i<promises.length;i++){ // promises[i].then(v=>{ //得知对象的状态是成功的 //每个promise对象都成功 count++; //将当前的promise对象成功的结果存入到数组中 arr[i]=v; if(count===promises.length){ resolve(arr); } },r=>{ reject(r); }) } }) } //添加race方法 Promise.race=function(promises){ return new Promise((resolve,reject)=>{ for(let i=0;i<promises.length;i++){ promises[i].then(v=>{ resolve(v); },r=>{ reject(r) }) } }); }