本文章也发布在掘金,附上地址:https://juejin.im/post/5de635865188251274248dbaPromise的实现首先分为三部分:promise的状态控制promise的后续处理Promise的串联promise的API分为原型成员(实例成员)和构造函数成员(静态成员)原型成员then:注册一个后续处理函数,当Promise为resolved状态时运行该函数catch: 注册一个后续处理函数,当Promise为rejected状态时运行该函数finally:[ES2018]注册一个后续处理函数(无参),当Promise为已决时运行该函数构造函数成员resolve(数据):该方法返回一个resolved状态的Promise,传递的数据作为状态数据,如果传递的数据是Promise,则直接返回传递的Promise对象reject(数据):该方法返回一个rejected状态的Promise,传递的数据作为状态数据all(iterable):这个方法返回一个新的promise对象,该promise对象在iterable参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个iterable里面的promise对象失败则立即触发该promise对象的失败。这个新的promise对象在触发成功状态以后,会把一个包含iterable里所有promise返回值的数组作为成功回调的返回值,顺序跟iterable的顺序保持一致;如果这个新的promise对象触发了失败状态,它会把iterable里第一个触发失败的promise对象的错误信息作为它的失败错误信息。Promise.all方法常被用于处理多个promise对象的状态集合。race(iterable):当iterable参数里的任意一个子promise被成功或失败后,父promise马上也会用子promise的成功返回值或失败详情作为参数调用父promise绑定的相应句柄,并返回该promise对象Promise状态控制实现promise状态控制实现: 首先实例化一个promise对象时,需要传递一个函数,该函数带有两个形参resolve,reject, 在实例化过程中会自动调用该函数(executor),执行传递的函数,实例化后得到promise对象带有两个属性,PromiseStatue,promiseValue, 当在该函数的执行体内调用executor的参数时(resolve,reject),会执行构造函数内相应的函数const MyPromise = (()=>{ const PENDING = "pending", RESOLVED = "resolved", REJECTED = "rejected", PromiseStatus = Symbol("PromiseStatus"), PromiseValue = Symbol("PromiseValue"), changeStatus = Symbol("changeStatus"); return class MyPromise{ /** * 改变当前Promise的状态 * @param {*} newStatus * @param {*} newValue * @param {*} queue */ [changeStatus](newStatus,newValue){ if(this[PromiseStatus !==PENDING]){ return; } this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; } constructor(executor){ this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; const resolve = data =>{ this[changeStatus](RESOLVED,data) } const reject = err =>{ this[changeStatus](REJECTED,err) } try{ //实例化一个新的promise对象时会传递一个函数,该函数带有resolve和reject两个形参,并且会自动调用该函数 executor(resolve,reject); }catch(err){ this[changeStatus](REJECTED,err) } } } })()+Promise的后续处理const MyPromise = (() => { const PENDING = "pending", RESOLVED = "resolved", REJECTED = "rejected", PromiseStatus = Symbol("PromiseStatus"), PromiseValue = Symbol("PromiseValue"), changeStatus = Symbol("changeStatus"), //新增 thenables = Symbol("thenables"), catchables = Symbol("catchables"), settleHandler = Symbol('settleHandler') return class MyPromise { [changeStatus](newStatus, newValue,queue) { if (this[PromiseStatus !== PENDING]) { return; } this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; //执行相应队列中的函数 queue.forEach(handler =>handler(newValue)) //这里会执行调用then/catch方法时还未达到已决状态时放入作业队列中的后续处理函数 } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; //新增 this[thenables] = []; this[catchables] = []; const resolve = data => { //修改 this[changeStatus](RESOLVED, data,this[thenables]) } const reject = err => { //修改 this[changeStatus](REJECTED, err,this[catchables]) } try { //实例化一个新的promise对象时会传递一个函数,该函数带有resolve和reject两个形参,并且会自动调用该函数 executor(resolve, reject); } catch (err) { //修改 this[changeStatus](REJECTED, err,this[catchables]) } } /**新增 * promise的后续函数 * @param {*} handler 后续处理函数 * @param {*} immediatelyStatus 需要立即执行的状态 * @param {*} queue 作业队列 */ [settleHandler](handler,immediatelyStatus,queue){ if(this[PromiseStatus] === immediatelyStatus){ setTimeout(()=>{ handler(this[PromiseValue]) }) }else{ queue.push(handler) } } /**新增 * Promise原型上的then方法 * @param {*} thenable then的处理函数 * @param {*} catchable catch的处理函数,如果传递了话 */ then(thenable, catchable) { this[settleHandler](thenable,RESOLVED,this[thenables]); this.catch(catchable);//该函数也会执行,但过不了settleHandler状态的一关,自然执行不了catch的后续处理函数 } /**新增 * Promise原型上的catch方法 * @param {*} catchable catch的处理函数 */ catch(catchable) { this[settleHandler](catchable,REJECTED,this[catchables]); } } })()then,catch后续处理: 当调用then/catch方法时,then会接受2个后续处理函数(thenable和catchable),catch会接收一个后续处理函数(catchable) ,如果此时状态处于未决阶段时,会把后续处理函数放入到作业队列里(微队列),等到变成已决阶段时才会从作业队列里按排列顺序(changeStatue中执行)执行作业队列里面的后续处理函数 ,如果此时状态已经处于已决阶段,会直接运行该后续处理函数,如果还是处于未决阶段时(参数数据均来自已决阶段得到的数据)+Promise的串联const MyPromise = (() => { const PENDING = "pending", RESOLVED = "resolved", REJECTED = "rejected", PromiseStatus = Symbol("PromiseStatus"), PromiseValue = Symbol("PromiseValue"), changeStatus = Symbol("changeStatus"), thenables = Symbol("thenables"), catchables = Symbol("catchables"), settleHandler = Symbol('settleHandler'), linkPromise = Symbol('linkPromise') return class MyPromise { [changeStatus](newStatus, newValue,queue) { if (this[PromiseStatus !== PENDING]) { return; } this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; //执行相应队列中的函数 queue.forEach(handler =>handler(newValue)) //这里会执行调用then/catch方法时还未达到已决状态时放入作业队列中的后续处理函数 } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[thenables] = []; this[catchables] = []; const resolve = data => { this[changeStatus](RESOLVED, data,this[thenables]) } const reject = err => { this[changeStatus](REJECTED, err,this[catchables]) } try { //实例化一个新的promise对象时会传递一个函数,该函数带有resolve和reject两个形参,并且会自动调用该函数 executor(resolve, reject); } catch (err) { this[changeStatus](REJECTED, err,this[catchables]) } } /** * promise的后续函数 * @param {*} handler 后续处理函数 * @param {*} immediatelyStatus 需要立即执行的状态 * @param {*} queue 作业队列 */ [settleHandler](handler,immediatelyStatus,queue){ if(typeof handler !== 'function'){ return; } if(this[PromiseStatus] === immediatelyStatus){ setTimeout(()=>{ handler(this[PromiseValue]) }) }else{ queue.push(handler) } } /**新增 * promise的串联:then/catch方法被调用后首先调用该函数,生成一个新的Promise对象并返回, * 然后then/catch为了要确认自身状态,需要调用settleHandler查看后续处理函数的运行状况,(通过接收运行返回的结果),如果返回的结果是一个可以按照正常逻辑走下去的非promise对象 ,则then方法返回的新Promise状态为resolved,如果是一个不能按照正常逻辑走下去的非Promise对象,则then方法返回的新Promise状态为rejected,如果返回的是一个promise对象, 新promise状态与该Promise状态的then方法返回的后续处理函数执行情况保持一致 * @param {*} thenalbe //then的后续处理函数 * @param {*} catchable //catch的后续处理函数 */ [linkPromise](thenable, catchable){ function exec(data,handler,resolve,reject){ try{ const result = handler(data)//得到的result是后续处理函数返回的结果 if(result instanceof MyPromise){ result.then(d=>{ resolve(d) },err=>{ reject(err) }) }else{ resolve(result) } }catch(err){ reject(err) } } return new MyPromise((resolve,reject)=>{ this[settleHandler](data=>{ exec(data,thenable,resolve,reject); },RESOLVED,this[thenables]) this[settleHandler](reason=>{ exec(reason,catchable,resolve,reject); },REJECTED,this[catchables]) }) } /**修改 * Promise原型上的then方法 * @param {*} thenable then的处理函数 * @param {*} catchable catch的处理函数,如果传递了话 */ then(thenable, catchable) { return this[linkPromise](thenable,catchable); } /**修改 * Promise原型上的catch方法 * @param {*} catchable catch的处理函数 */ catch(catchable) { return this[linkPromise](undefined,catchable); } } })()3.串联Promise: 应用场景:当后续的Promise需要用到之前的Promise的处理结果时,需要Promise的串联promise对象中,无论是then方法还是catch方法,他们都具有返回值,返回的是一个全新的promise对象(return new Promise),该Promise的状态取决于后续处理函数, 如果该后续处理函数还没执行,还在作业队列里,则返回的Promise的状态是挂起状态(pandding),如果该后续处理函数已经在执行,说明该then自身的Promise对象进入了 已决状态(resolve或reject),如果后续处理函数能顺利执行,并返回了值,则then方法创建的全新Promise的状态变为Resolve,(参数数据为then方法return回来的数据) 如果后续处理函数在执行过程中发生了错误,(有报错),则该全新的Promise进入reject状态,(参数数据为报错的数据) 如果前面的Promise的后续处理函数在能顺利执行后,返回的值是一个Promise对象,则返回的新的Promise状态和后续处理返回的Promise状态保持一致, 注意并不是跟返回的Promise的后续处理函数执行状态保持一致(意思就是状态重新配对 return 的promise对象的状态,之前的无效) (参数来自 已决阶段的后续处理函数返回的参数)至此,Promsie的功能基本实现。const MyPromise = (() => { const PENDING = "pending", RESOLVED = "resolved", REJECTED = "rejected", PromiseStatus = Symbol("PromiseStatus"), PromiseValue = Symbol("PromiseValue"), changeStatus = Symbol("changeStatus"), thenables = Symbol("thenables"), catchables = Symbol("catchables"), settleHandler = Symbol('settleHandler'), linkPromise = Symbol('linkPromise') return class MyPromise { [changeStatus](newStatus, newValue,queue) { if (this[PromiseStatus !== PENDING]) { return; } this[PromiseStatus] = newStatus; this[PromiseValue] = newValue; //执行相应队列中的函数 queue.forEach(handler =>handler(newValue)) //这里会执行调用then/catch方法时还未达到已决状态时放入作业队列中的后续处理函数 } constructor(executor) { this[PromiseStatus] = PENDING; this[PromiseValue] = undefined; this[thenables] = []; this[catchables] = []; const resolve = data => { this[changeStatus](RESOLVED, data,this[thenables]) } const reject = err => { this[changeStatus](REJECTED, err,this[catchables]) } try { //实例化一个新的promise对象时会传递一个函数,该函数带有resolve和reject两个形参,并且会自动调用该函数 executor(resolve, reject); } catch (err) { this[changeStatus](REJECTED, err,this[catchables]) } } /** * promise的后续函数 * @param {*} handler 后续处理函数 * @param {*} immediatelyStatus 需要立即执行的状态 * @param {*} queue 作业队列 */ [settleHandler](handler,immediatelyStatus,queue){ if(typeof handler !== 'function'){ return; } if(this[PromiseStatus] === immediatelyStatus){ setTimeout(()=>{ handler(this[PromiseValue]) }) }else{ queue.push(handler) } } /**新增 * promise的串联:then/catch方法被调用后首先调用该函数,生成一个新的Promise对象并返回, * 然后then/catch为了要确认自身状态,需要调用settleHandler查看后续处理函数的运行状况,(通过接收运行返回的结果),如果返回的结果是一个可以按照正常逻辑走下去的非promise对象 ,则then方法返回的新Promise状态为resolved,如果是一个不能按照正常逻辑走下去的非Promise对象,则then方法返回的新Promise状态为rejected,如果返回的是一个promise对象, 新promise状态与该Promise状态的then方法返回的后续处理函数执行情况保持一致 * @param {*} thenalbe //then的后续处理函数 * @param {*} catchable //catch的后续处理函数 */ [linkPromise](thenable, catchable){ function exec(data,handler,resolve,reject){ try{ const result = handler(data)//得到的result是后续处理函数返回的结果 if(result instanceof MyPromise){ result.then(d=>{ resolve(d) },err=>{ reject(err) }) }else{ resolve(result) } }catch(err){ reject(err) } } return new MyPromise((resolve,reject)=>{ this[settleHandler](data=>{ exec(data,thenable,resolve,reject); },RESOLVED,this[thenables]) this[settleHandler](reason=>{ exec(reason,catchable,resolve,reject); },REJECTED,this[catchables]) }) } /**修改 * Promise原型上的then方法 * @param {*} thenable then的处理函数 * @param {*} catchable catch的处理函数,如果传递了话 */ then(thenable, catchable) { return this[linkPromise](thenable,catchable); } /**修改 * Promise原型上的catch方法 * @param {*} catchable catch的处理函数 */ catch(catchable) { return this[linkPromise](undefined,catchable); } } })()其他APIPromise.resolve()static resolve(data){ if(data instanceof Mypromise){ return data }else{ return new MyPromise((resolve,reject)=>{ resolve(data); }) } }静态resolve方法,静态resolve方法接受一个参数,如果该参数不是Promise对象,返回一个resolve状态的新Promise 如果该参数是一个promise对象,直接返回该promise对象 2. Promise.reject()static reject(reason){ //写两个参数是因为这这是形参,真正的reject在第二位参数位置 return new MyPromise((resolve,reject)=>{ reject(reason) }) }静态reject方法:接收一个参数,返回一个reject状态的Promise对象 3. Promise.race()static race(proms){ return new Promise((resolve,reject)=>{ proms.forEach(pro=>{ pro.then(data=>{ resolve(data); },err=>{ reject(err); }) }) }) }静态race方法:接受一个由promise对象组成的数组,返回一个首先到达已决阶段的promise对象 4. Promise.all()static all(proms) { return new Promise((resolve, reject) => { const results = proms.map(p => { const obj = { result: undefined, isResolved: false } p.then(data => { obj.result = data; obj.isResolved = true; //判断是否所有的全部完成 const unResolved = results.filter(r => !r.isResolved) if (unResolved.length === 0) { //全部完成 resolve(results.map(r => r.result)); } }, reason => { reject(reason); }) return obj; }) }) }