Promise
的用法 :
let p = new Promise(function(resolve, reject){ console.log(111) setTimeout(function(){ resolve(2) }, 1000)})p.then(function(res){ console.log('suc',res)},function(err){ console.log('err',err)})
能够看到new了一个Promise,外面有一个回调函数,回调函数里有2个参数,别离又是另外2个函数。其实外面很多也都是回调函数的封装调用。
const [PENDING,RESOLVED,REJECTED]=["PENDING","RESOLVED","REJECTED"];`class Promise1 { constructor(executor){ state = PENDING; value = undefined; reason = undefined; resolve = (value) => { if(this.state === PENDING){ this.state = RESOLVED; this.value = value; } } reject = (reason) => { if(this.state === PENDING){ this.state = REJECTED; this.value = reason; } } try{ executor(this.resolve,this.reject) }catch(e){ reject(e) } } }
测试一下执行状况:
let p1 = new Promise1((resolve,reject)=>{//function:executor console.log(111) setTimeout(()=>{ resolve(111)//this.resolve,间接传参调用 }, 1000)})
上面就是then
了
class Promise1 { constructor(executor){ ... onResolvedCallbacks=[]; //then,pending里先存起来 onRejectedCallbacks=[]; ... resolve = (value) => { if(this.state === PENDING){ ... //executor里如果是异步会把then里存起来,而后executor走完了resolved的话,会再调then里回调函数 this.onResolvedCallbacks.forEach(fn => fn(value)) } } reject = (reason) => { if(this.state === PENDING){ ... this.onRejectedCallbacks.forEach(fn => fn(reason)) } } } then(onResolved,onRejected){ onResolved = typeof onResolved === 'function' ? onResolved : value => value; onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }; switch(this.state){ case RESOLVED : //状态变了,就间接把后果给进来 onResolved(this.value); case REJECTED : onRejected(this.reason); case PENDING : //如果是pending的话,阐明executor还没走完,先存起来,走完再调用 this.onResolvedCallbacks.push(onResolved); this.onRejectedCallbacks.push(onRejected) } }}
测试一下 :
let p2 = new Promise1((resolve, reject) => { setTimeout(()=>{ resolve(222) }, 1000)})p2.then(res => console.log(res, 'res')) //222
链式调用:
class Promise1 { ... then(onResolved,onRejected){ ... //返回一个promise1 let newPromise=new Promise1((resolve,reject)=>{ switch(this.state){ case RESOLVED : //状态变了,就间接把后果给进来 setTimeout(()=>{//then,放前面解决 try{ let reValue=onResolved(this.value); rePromise(newPromise,reValue,resolve,reject) }catch(e){reject(e)} },0) case REJECTED : setTimeout(()=>{ try{ let reValue=onRejected(this.reason); rePromise(newPromise,reValue,resolve,reject) }catch(e){reject(e)} },0) case PENDING : //如果是pending的话,阐明executor还没走完,先存起来,走完再调用 this.onResolvedCallbacks.push(()=>{ setTimeout(()=>{ try{ let reValue=onResolved(this.value); rePromise(newPromise,reValue,resolve,reject) }catch(e){reject(e)} },0) }); this.onRejectedCallbacks.push(()=>{ setTimeout(()=>{ try{ let reValue=onRejected(this.reason); rePromise(newPromise,reValue,resolve,reject) }catch(e){reject(e)} },0) }) } }) return newPromise; }}//newPromise:新的promise1对象,reValue:上一个then的返回值,newPromise.resolve,newPromise.rejectfunction rePromise(newPromise,reValue,resolve,reject){ //相当于把本人return进来了,let p2 = p.then(res => p2); if(newPromise === reValue){ reject(new TypeError('循环了')) } if(reValue !== null && (typeof reValue === 'object' || typeof reValue === 'function')){ try{ //判断一下reValue是不是promise1,是个对象,还带有then函数 //如果有then并是个函数,就调then; let then = reValue.then; if(typeof then === 'function'){ then.call(reValue, res=>{ resolve(res) },err=>{ reject(err) }) }else{//then不是函数,间接用resolve返回值 resolve(reValue) } }catch(e){ reject(e) } }else{//只是个一般值 resolve(reValue) }}
测试一下:
p3.then(res => { console.log(res) return new Promise1((resolve, reject) => { resolve('p3') })}).then(res => console.log(res, 'pp3'))//p3
但还有个问题
...function rePromise(newPromise,reValue,resolve,reject){ ... let called;//是否调用过,避免屡次调用 if(reValue !== null && (typeof reValue === 'object' || typeof reValue === 'function')){ try{ let then = reValue.then; if(typeof then === 'function'){ then.call(reValue, res=>{ if(called) return; called = true; //promise1就持续下一个,直到then走完,变成一般的值 rePromise(newPromise,res,resolve,reject) },err=>{ if(called) return; called = true; reject(err) }) }else{//then不是函数,间接用resolve返回值 resolve(reValue) } }catch(e){ if(called) return; called = true; reject(e) } }else{//只是个一般值 resolve(reValue) }}
测试一下
let p1=new Promise1((resolve,reject)=>{ resolve(111) }) let p2=p1.then(res=>{console.log(res,'p1')},err=>console.log(err,'p1')); p2.then(res=>console.log(res,'p2')) .then(res=>console.log(res,'p3))
还有其它属性:
class Promise1 { ... catch(onReject){ return this.then(null,onReject) } defer(){ let defer={}; defer.promise=new Promise1((resolve,reject)=>{ defer.resolve=resolve; defer.reject=reject; }) return defer; } deffered(){ return this.defer; } all(promises){ return new Promise1((resolve,reject)=>{ let done=gen(promises.length,resolve); for(let i=0;i<promises.length,i++){ promises[i].then(res=>{ done(i,res) },reject) } }) } race(promises){ return new Promise1((resolve,reject)=>{ for(let i=0;i<promises.length;i++){ promises[i].then(resolve,reject) } }) } resolve(value){ return new Promise1((resolve,reject)=>{ resolve(value) }) } reject(reason){ return new Promise1((resolve,reject)=>{ reject(reason) }) }}function gen(times,cb){ const result=[]; let count=0; return (i,data)=>{ result[i]=data; count+=1; if(count===times){ cb(result) } }}