js异步解决方案常用来解决js异步方法回调回调,简单粗暴,但是有回调地狱functiona(call){console.log('resultbymethoda')call&&call()}functionb(){console.log('resultreturnedbymethodb')}//方法a执行后,方法ba(b)被执行。这种写法最大的问题是:如果有这样一个业务场景,有A、B、C三个异步函数,其中B的执行需要在A执行完之后执行,C的执行需要在B之后执行。这个场景模拟成代码(以jquery中的ajax方法为例)ajax(url,()=>{//处理逻辑ajax(url1,()=>{//处理逻辑ajax(url2,()=>{//处理逻辑})})})事件监听器a.on('done',b);letEvent=function(){this.handler={}}Event.prototype.emit=function(eventName,eventDate){leteventHandler=this.handler[eventName]if(!eventHandler){return}eventHandler.map(fn=>fn(eventDate))}Event.prototype.on=function(eventName,callback){如果(!this.handler[eventName]){this.handler[eventName]=[]}this.handler[eventName].push(callback)}leteventCenter=newEvent()eventCenter.on('aEnd',function(res){b(res)})functionb(res){console.log(res)}functiona(x){前夕ntCenter.emit('aEnd',x)}a('a返回的参数')发布订阅模式varsalesOffices={};salesOffices.clientList=[];//缓存列表,存储订阅者的回调函数,即RostersalesOffices.listen=function(fn){//添加订阅者this.clientList.push(fn);//订阅的消息被添加到缓存列表};salesOffices.trigger=function(){//发布消息for(vari=0;i{b()})functionb(res){console.log('方法b返回的结果')}Generators/yieldfunctiona(){console.log('方法a返回的结果')}function*b(){yielda()console.log('方法b返回的结果')}letb1=b()b1.next()b1.next()async/awaitfunctionfnA(){returnnewPromise(resolve=>{...//异步操作中resolve})}functionfnB(){returnnewPromise(resolve=>{...//异步操作中resolve})}functionfnC(){returnnewPromise(resolve=>{...//异步操作中resolve})}asyncfunctiongen(){letresA=awaitfnA()letresB=awaitfnB(resA)letresC=awaitfnC(resB)}gen()常见面试题,手写PromiseconstPEDDING='PEDDING'constRESOLVE='RESOLVE'constREJECT='REJECT'consthandlePromise=(result,newPromise,resolve,reject)=>{if(typeofresult==='object'&&result!==null||typeofresult=复制代码=='function'){constthen=result.thenif(typeofthen==='function'){then.call(result,r=>{handlePromise(r,newPromise,resolve,reject)},err=>{reject(err)})}else{resolve(result)}}else{resolve(result)}}classNewPromise{status=PEDDINGresult=undefined原因=undefinedonResolvedCallBacks=[]onRejectedCallBacks=[]constructor(exc){constresolve=result=>{if(this.status===PEDDING){this.result=resultthis.status=RESOLVEthis.onResolvedCallBacks.forEach(fn=>fn())}}constreject=reason=>{if(this.status===PEDDING){this.reason=reasonthis.status=REJECTthis.onRejectedCallBacks.forEach(fn=>fn())}}exc(resolve,reject)}then(onResolve,onReject){constnewPromse=newNewPromise((resolve,reject)=>{if(this.status===RESOLVE){setTimeout(()=>{letresult=onResolve(this.result)handlePromise(result,newPromse,resolve,reject)},0);}if(this.status===REJECT){setTimeout(()=>{让结果=onReject(this.reason)handlePromise(result,newPromse,resolve,reject)},0);}我f(this.status===PEDDING){this.onResolvedCallBacks.push(()=>{letresult=onResolve(this.result)handlePromise(result,newPromse,resolve,reject)})this.onRejectedCallBacks.push(()=>{letresult=onReject(this.reason)handlePromise(result,newPromse,resolve,reject)})}})returnnewPromse}catch(onReject){returnthis.then(null,onReject);}finally(onFinally){returnthis.then(onFinally,onFinally);}}NewPromise.all=function(allp){letlist=[]letlen=0lethasErr=falsereturnnewNewPromise((resolve,reject)=>{for(leti=0;i{list[i]=reslen++len===allp.length&&resolve(list)},err=>{!hasErr&&reject(err)hasErr=true})}})}NewPromise.race=function(allp){让hasValue=false让hasErr=falsereturnnewNewPromise((resolve,reject)=>{for(leti=0;i{!hasValue&&!hasErr&&resolve(res)hasValue=true},err=>{!hasValue&&!hasErr&&reject(err)hasErr=true})}})}