Open libin1991 opened 6 years ago
Promise是异步编程的一种解决方案,比回调函数和事件更合理更强大。
原生的promise用法如下:
let p=new Promise(function(resolve,reject){ resolve('成功'); //reject('失败'); }); p.then(function(data){ console.log(data); },function(err){ console.log(err); });
Promise实例中有一个函数,接受两个参数,一个是成功的方法,一个是失败的方法,然后有一个then方法,第一个是成功执行的函数,第二个是失败执行的函数,并且会接收相应的参数。一旦执行成功,就不会再执行失败,反之亦然。
function Promise(executor){ //executor是一个执行函数 let self = this; self.status = 'pending'; self.value = undefined; //默认成功的值 self.reason = undefined; //默认失败的值 function resolve(value){ //成功状态 if(self.status === 'pending'){ self.status = 'resolved'; self.value = value; } } function reject(reason){ //失败状态 if(self.status === 'pending'){ self.status = 'rejected'; self.reason = reason; } } try{ executor(resolve,reject); }catch(e){ //处理异常状态,传给reject reject(e); } }; Promise.prototype.then = function(onFulfilled,onRejected){ let self = this; if(self.status === 'resolved'){ onFulfilled(self.value); } if(self.status === 'rejected'){ onRejected(self.reason); } }; module.exports = Promise;
首先先定义一个Promise函数,并且接受一个executor执行函数,将resolve和reject传参传进去,定义私有属性status,value,reason。 Promise有三个状态,status用来记录他们: 初始状态为pending 成功状态为resolved 失败状态为rejected
然后使用prototype挂载一个then方法, 方法中要传入一个成功的回掉和一个失败的回掉, 如果成功就调取成功的回掉, 失败就调取失败的回掉
最后将函数导出,就实现了一个最基础功能的Promise。
但是这个Promise还是一个同步的方法,如果想在代码中使用异步,比如:
let p=new Promise(function(resolve,reject){ setTimeout(function(){ resolve('成功'); },1000); //throw new Error('错误'); });
我们就需要将他变为异步的:
function Promise(executor){ let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.onResolvedCallbacks= []; //存放成功的回掉 self.onRejectedCallbacks= []; //存放失败的回掉 function resolve(value){ if(self.status === 'pending'){ self.status = 'resolved'; self.value = value; self.onResolvedCallbacks.forEach(function(fn){ fn(); }); } } function reject(reason){ if(self.status === 'pending'){ self.status = 'rejected'; self.reason = reason; self.onRejectedCallbacks.forEach(function(fn){ fn(); }); } } try{ executor(resolve,reject); }catch(e){ //处理异常状态,传给reject reject(e); } } Promise.prototype.then=function(onFulfilled,onRejected){ let self = this; if(self.status === 'resolved'){ onFulfilled(self.value); } if(self.status === 'rejected'){ onRejected(self.reason); } if(self.status === 'pending'){ self.onResolvedCallbacks.push(function(){ onFulfilled(self.value); }); self.onRejectedCallbacks.push(function(){ onRejected(self.reason); }); } }; module.exports = Promise;
如果他是异步的,我们就不能在then方法中用status的成功失败状态来判断他走的那,因为then方法执行后有可能params中还没执行resolve或者reject,那么我们就在Promise实例上再新增onResolvedCallbacks和onRejectedCallbacks两个数组来存放他的回掉,如果执行的是成功,失败就会存默认的undefined。在调用时用forEach循环数组依次知性方法。 原生的Promise还可以then多次:
function Promise(executor){ let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.onResolvedCallbacks= []; self.onRejectedCallbacks= []; function resolve(value){ self.status = 'resolved'; self.value = value; self.onResolvedCallbacks.forEach(function(fn){ fn(); }); } function reject(reason){ self.status = 'rejected'; self.reason = reason; self.onRejectedCallbacks.forEach(function(fn){ fn(); }); } try{ executor(resolve,reject); }catch(e){ reject(e); } }; Promise.prototype.then = function(onFulfilled,onRejected){ let self = this; let promise2; //实现链式操作 if(self.status === 'resolved'){ promise2 = new Promise(function(resolve, reject){ try{ let x = onFulfilled(self.value); resolve(x); }catch(e){ reject(e); } }); } if(self.status === 'rejected'){ promise2 = new Promise(function(resolve, reject){ try{ let x = onRejected(self.reason); reject(x); }catch(e){ reject(e); } }); } if(self.status === 'pending'){ promise2 = new Promise(function(resolve, reject){ self.onResolvedCallbacks.push(function(){ try{ let x = onFulfilled(self.value); resolve(x); }catch(e){ reject(e); } }); self.onRejectedCallbacks.push(function(){ try{ let x = onRejected(self.reason); reject(x); }catch(e){ reject(e); } }); }); } return promise2; } module.exports = Promise;
当然他then的链式调用不会有then属性,所以我们可以判断Promise每次then都会new一个新的Promise我们用Promise2来表示,then的时候new一个新的Promise并且return给下一个then。 then中无论是成功的回掉还是失败的毁掉,只要返回了结果,就会走下一个then中的成功,发生错误才会走下一个then中的失败,then中可以return普通值,也可return一个新的Promise,还有可能return 一个{then:xxx},当然更有promise.then().then.then(function(){});这种奇葩的用法
function Promise(executor){ let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.onResolvedCallbacks= []; self.onRejectedCallbacks= []; function resolve(value){ self.status = 'resolved'; self.value = value; self.onResolvedCallbacks.forEach(function(fn){ fn(); }); } function reject(reason){ self.status = 'rejected'; self.reason = reason; self.onRejectedCallbacks.forEach(function(fn){ fn(); }); } try{ executor(resolve,reject); }catch(e){ reject(e); } }; function resolvePromise(p2,x,resolve,reject){ //1.处理乱写 //2.判断返回的是不是自己 if(p2 === x){ reject(new typeError('循环引用')); } //判断x是不是params(判断x是不是object) let called; //表示是否调用过成功或者失败 if(x !== null || typeof x === 'object' || typeof x === 'function'){ //判断promise只要判断对象中是否有then方法 try{ letthen = x.then; if(typeof then === 'function'){ //then返回的可能是{then:xxx},判断then是不是一个函数 then.call(x,function(y){ //成功了以后可能会执行resolve(new Promise())用递归来解决 if(called) return; called = true; resolvePromise(p2,y,resolve,reject); },function(err){ if(called) return; called = true; reject(err); }); }else{ resolve(x); } }catch(e){ if(called) return; called = true; reject(e); } }else{ //esle普通值 resolve(x); } } Promise.prototype.then = function(onFulfilled,onRejected){ //判断onFulfilled是不是一个函数,不是给他个函数 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value){ return value; } onRejected = typeof onRejected === 'function' ? onRejected : function(err){ throw err; } let self = this; let promise2; //实现链式操作 if(self.status === 'resolved'){ promise2 = new Promise(function(resolve, reject){ let x = onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }); } if(self.status === 'rejected'){ promise2 = new Promise(function(resolve, reject){ let x = onRejected(self.reason); resolvePromise(promise2,x,resolve,reject); }); } if(self.status === 'pending'){ promise2 = new Promise(function(resolve, reject){ self.onResolvedCallbacks.push(function(){ let x = onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }); self.onRejectedCallbacks.push(function(){ let x = onRejected(self.reason); resolvePromise(promise2,x,resolve,reject); }); }); } return promise2; } module.exports = Promise;
我们就定义一个resolvePromise来处理then中的返回结果,如果返回的是个错误信息,就用try{}catch(){}让他走reject 最后的最后,Promise中可以异步执行代码,then方法中应该也可以实现异步,很简单,只要在相应的位置加上setTimeout就ok了,记得不要忘了加上try{}catch(){}来过滤错误信息并且传到reject中
function Promise(executor){ let self = this; self.status = 'pending'; self.value = undefined; self.reason = undefined; self.onResolvedCallbacks= []; self.onRejectedCallbacks= []; function resolve(value){ self.status = 'resolved'; self.value = value; self.onResolvedCallbacks.forEach(function(fn){ fn(); }); } function reject(reason){ self.status = 'rejected'; self.reason = reason; self.onRejectedCallbacks.forEach(function(fn){ fn(); }); } try{ executor(resolve,reject); }catch(e){ reject(e); } }; function resolvePromise(p2,x,resolve,reject){ //1.处理乱写 //2.判断返回的是不是自己 if(p2 === x){ reject(new typeError('循环引用')); } //判断x是不是params(判断x是不是object) let called; //表示是否调用过成功或者失败 if(x !== null || typeof x === 'object' || typeof x === 'function'){ //判断promise只要判断对象中是否有then方法 try{ letthen = x.then; if(typeof then === 'function'){ //then返回的可能是{then:xxx},判断then是不是一个函数 then.call(x,function(y){ //成功了以后可能会执行resolve(new Promise())用递归来解决 if(called) return; called = true; resolvePromise(p2,y,resolve,reject); },function(err){ if(called) return; called = true; reject(err); }); }else{ resolve(x); } }catch(e){ if(called) return; called = true; reject(e); } }else{ //esle普通值 resolve(x); } } Promise.prototype.then = function(onFulfilled,onRejected){ //判断onFulfilled是不是一个函数,不是给他个函数 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : function(value){ return value; } onRejected = typeof onRejected === 'function' ? onRejected : function(err){ throw err; } let self = this; let promise2; //实现链式操作 if(self.status === 'resolved'){ promise2 = new Promise(function(resolve, reject){ setTimeout(function(){ try{ let x = onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); } if(self.status === 'rejected'){ promise2 = new Promise(function(resolve, reject){ setTimeout(function(){ try{ let x = onRejected(self.reason); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); } if(self.status === 'pending'){ promise2 = new Promise(function(resolve, reject){ self.onResolvedCallbacks.push(function(){ setTimeout(function(){ try{ let x = onFulfilled(self.value); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); self.onRejectedCallbacks.push(function(){ setTimeout(function(){ try{ let x = onRejected(self.reason); resolvePromise(promise2,x,resolve,reject); }catch(e){ reject(e); } }) }); }); } return promise2; } module.exports = Promise;
Promise是异步编程的一种解决方案,比回调函数和事件更合理更强大。
原生的promise用法如下:
Promise实例中有一个函数,接受两个参数,一个是成功的方法,一个是失败的方法,然后有一个then方法,第一个是成功执行的函数,第二个是失败执行的函数,并且会接收相应的参数。一旦执行成功,就不会再执行失败,反之亦然。
首先先定义一个Promise函数,并且接受一个executor执行函数,将resolve和reject传参传进去,定义私有属性status,value,reason。 Promise有三个状态,status用来记录他们: 初始状态为pending 成功状态为resolved 失败状态为rejected
然后使用prototype挂载一个then方法, 方法中要传入一个成功的回掉和一个失败的回掉, 如果成功就调取成功的回掉, 失败就调取失败的回掉
最后将函数导出,就实现了一个最基础功能的Promise。
但是这个Promise还是一个同步的方法,如果想在代码中使用异步,比如:
我们就需要将他变为异步的:
如果他是异步的,我们就不能在then方法中用status的成功失败状态来判断他走的那,因为then方法执行后有可能params中还没执行resolve或者reject,那么我们就在Promise实例上再新增onResolvedCallbacks和onRejectedCallbacks两个数组来存放他的回掉,如果执行的是成功,失败就会存默认的undefined。在调用时用forEach循环数组依次知性方法。 原生的Promise还可以then多次:
当然他then的链式调用不会有then属性,所以我们可以判断Promise每次then都会new一个新的Promise我们用Promise2来表示,then的时候new一个新的Promise并且return给下一个then。 then中无论是成功的回掉还是失败的毁掉,只要返回了结果,就会走下一个then中的成功,发生错误才会走下一个then中的失败,then中可以return普通值,也可return一个新的Promise,还有可能return 一个{then:xxx},当然更有promise.then().then.then(function(){});这种奇葩的用法
我们就定义一个resolvePromise来处理then中的返回结果,如果返回的是个错误信息,就用try{}catch(){}让他走reject 最后的最后,Promise中可以异步执行代码,then方法中应该也可以实现异步,很简单,只要在相应的位置加上setTimeout就ok了,记得不要忘了加上try{}catch(){}来过滤错误信息并且传到reject中