Promise是一种异步编程的解决方案,比传统的回调函数或事件更加合理和灵活。本文主要展示Promise提供的方法列表,以及基本的实现原理。通过本文,我们可以加深对Promise方法的理解和使用,对Promise.all、Promise.race、Promise.allSettled和Promise.any这四种方法的异同有更深刻的理解。1.Promise方法列表Promise有3个实例方法:then/catch/finally,6个静态方法:all/race/allSettled/any/resolve/reject。其中then的实现会比较复杂,因为涉及到PromiseResolutionProcedure(承诺解决程序),其余都是基于现有功能的扩展。下面列出了所有方法。Promise.prototype.then()Promise.prototype.catch()Promise.prototype.finally()Promise.all()Promise.race)Promise.allSettled)Promise.any()Promise.resolve()Promise.reject()二9Promise实现1.原型方法then方法是整个Promise解决方案的核心内容,由于回调函数和返回一个新的Promise实例,解决过程比较复杂。//类MyPromise{//staticPENDING='pending';//进行中//staticFULFILLED='fulfilled';//成功//staticREJECTED='rejected';//失败//state=MyPromise.PENDING;//value=null;//reason=null;//onFulfilledCallbacks=[];//onRejectedCallbacks=[];//...//}MyPromise.prototype.then=(onFulfilled,onRejected)=>{if(typeofonFulfilled!='function'){onFulfilled=(value)=>value;}if(typeofonRejected!='function'){onRejected=(reason)=>{throwreason;};}//Promise核心解析过程参考规范2.3const_resolvePromise=(promise,x,resolve,reject)=>{//2.3.1如果promise和x指向同一个对象,则抛出TypeError错误if(promise===x){consterrMsg='promise和返回值相同';返回拒绝(新类型错误(errMsg));}//2.3.3如果x是对象(不为空)或函数if((typeofx==='object'&&x!==null)||typeofx==='function'){letthen=努二;尝试{//2.3.3.1。检索属性x.thenthen=x.then;}catch(error){//2.3.3.2如果x.then导致抛出异常e,则拒绝以e为拒绝原因的promisereturnreject(error);}//2.3.3.3如果then是一个函数,x作为then的this调用方法,第一个参数是成功的回调函数,第二个参数是失败的回调函数if(typeofthen==='函数'){让调用=false;try{then.call(x,(y)=>{//2.3.3.3.4如果成功回调和失败回调都被调用或者多次调用同一个参数,第一次调用优先,其他所有调用将被忽略if(called)return;called=true;//2.3.3.3.1如果使用值y调用成功回调,运行[[Resolve]](promise,y)_resolvePromise(promise,y,resolve,reject);},(r)=>{//2.3.3.3.4如果成功回调和失败回调都被调用或者多次调用同一个参数,第一次调用优先,其他调用将被忽略。如果(称为)返回;称为=真;//2.3.3.3.2如果因原因r调用失败回调,则使用rreject(r)拒绝promise;});}catch(error){//2.3.3.4ifcalledthen方法抛出异常e://2.3.3.4.1如果调用成功回调或失败回调,则忽略if(called)return;//2.3.3.4.2未调用,使用e作为拒绝承诺的原因reject(error);}}else{//2.3.3.4。如果then不是函数,则以x为值完成promisereturnresolve(x);}}else{//2.3.4如果x不是对象或函数,则使用x作为参数Executepromisereturnresolve(x);}};//链式返回的PromiseconstnewPromise=newMyPromise((resolve,reject)=>{switch(this.state){caseMyPromise.FULFILLED:setTimeout(()=>{try{constx=onFulfilled(this.value);_resolvePromise(newPromise,x,resolve,reject);}catch(reason){reject(reason);}},0);中断;caseMyPromise.REJECTED:setTimeout(()=>{try{constx=onRejected(this.reason);_resolvePromise(newPromise,x,resolve,reject);}catch(reason){reject(reason);}},0);休息;caseMyPromise.PENDING:this.onFulfilledCallbacks.push(()=>{setTimeout(()=>{try{constx=onFulfilled(this.value);_resolvePromise(newPromise,x,resolve,reject);}catch(原因){拒绝(原因);}},0);});this.onRejectedCallbacks.push(()=>{setTimeout(()=>{try{constx=onRejected(this.reason);_resolvePromise(newPromise,x,resolve,reject);}catch(reason){reject(reason));}},0);});休息;}});返回新承诺;};2。原型方法catch如果上面如果没有定义reject方法或者抛出错误,所有的异常都会转到catch方法,catch可以复用then方法MyPromise.prototype.catch=function(onRejected){returnthis.then(null,onRejected);};3。finally原型方法不管是resolve还是reject都会调用finally。那么就相当于finlly方法为用户分别调用了then的resolved和rejected状态回调。MyPromise.prototype.finally=function(fn){returnthis.then((value)=>{fn();returnvalue;},(reason)=>{fn();throwreason;});};4.静态方法Promise.allPromise.all()方法用于将多个Promise实例包装成一个新的Promise实例。对所有参数数组Promise实例执行完resolve回调后,新实例执行resolve回调;如果中间有任何一个Promise实例执行了reject回调,则新实例直接执行reject回调。比如:多个员工同时在做多个项目,你要求任何一个项目都必须让你满意。如有一处不满意,视为本次活动(所有项目)失败。重点是整体满意度。MyPromise.all=function(promises){returnnewPromise((resolve,reject)=>{if(promises.length===0){resolve([]);}else{letresult=[];letindex=0;for(leti=0;i
