promise简单实现
function isFunction(fn){ return Object.prototype.toString.call(fn) === '[object Function]'; } let ST = { pending: 0, resolved: 1, rejected: 2 } function Promise(fn){ let self = this; self.status = ST.pending; self.value = ''; self.reason = ''; self.resolveFns = []; self.rejectFns = []; //setTimeout延迟执行,将reslove执行放在下个循环,保证后续then方法先于它执行,不会出现前面已经resolve了,后面的then还没push进resolveFns数组 function resolve(val){ setTimeout(() => { if(self.status == ST.pending){ self.status = ST.resolved; self.value = val; //用数组保存回调,是为了处理一个promise挂载多个then的情况 //注意不是链式,这种场景很少出现 /* 形如: promise.then(resolve1,reject1) promise.then(resolve2,reject2) promise.then(resolve3,reject3) */ //在链式调用中,该数组通常只会有一个项,就是当前promise的下一个then里面的resolve函数 //且每次执行,通常都是一个新Promise的resolve数组 self.resolveFns.forEach(fn => fn()); } }) } function reject(val){ setTimeout(() => { if(self.status == ST.pending){ self.status = ST.rejected; self.reason = val; self.rejectFns.forEach(fn => fn()); } }) } //执行出问题,直接reject,Promise的错误默认不会抛出到全局 try{ fn(resolve,reject); } catch(err){ reject(err); } } Promise.prototype.then = function(onResolve,onReject){ let self = this; //then每次执行都返回一个新的Promise,then方法要处理前一个promise的三种状态 return new Promise(function(resolve,reject){ function handle(value,thenFn){ let res = isFunction(thenFn) && thenFn(value) || value; if(res instanceof Promise){ res.then(resolve,reject); } else{ resolve(res); } } //处理三种状态 //fn函数体里,如果有错误; 会执行try catch里的 reject方法,执行then this.state就是rejected //如果没错误且没异步,resolve this.state就是resolved //如果没错误且有异步,this.state就是pending if(self.status == ST.pending){ self.resolveFns.push(resloveHandle); self.rejectFns.push(rejectHandle); } else if(self.status == ST.resolved){ self.handle(self.value,onResolve); } else if(this.status == ST.rejected){ self.handle(self.reason,onReject); } }) } Promise.prototype.catch = function(onReject){ return this.then(undefined, onReject); } //finally不是promise的末尾,后面还可以有then,所以value和reason必须可以向下传递 Promise.prototype.finally = function(fn){ let P = this.constructor; return this.then( value => P.resolve(fn()).then(() => value), reason => P.resolve(fn()).then(() => throw reason); ) } //done作为promise的末尾,用于收集所有可能的报错,catch方法捕捉所有错误,并抛出 Promise.prototype.done = function(resolve,reject){ return this.then(resolve, reject).catch(function(reason){ setTimeout(function(){ throw reason; }); }) } Promise.resolve = function(val){ return new Promise((resolve) => { resolve(val); }) } Promise.reject = function(val){ return new Promise((resolve,reject) => { reject(val); }) } Promise.race = function(promises){ let len = promises.length; return new Promise(function(resolve,reject){ while(len--){ promises[len].then(resolve,reject); } }) } Promise.all = function(promises){ let len = promises.length, results = []; return new Promise(function(resolve,reject){ //用一个数组收集单个promise执行后的结果,收集满数组所有结果,便是所有执行成功 function reslove(index){ return function(value){ results[index] = value; if(results.length == len){ reslove(results); } } } while(len--){ promises[len].then(resolve(len),reject); } }) }