欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    Promise由浅入深介绍.pdf

    • 资源ID:90876999       资源大小:1,017.58KB        全文页数:17页
    • 资源格式: PDF        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    Promise由浅入深介绍.pdf

    在我的上一篇文章里着重介绍了 async的相关知识,对promise的提及甚少,现在很多面试也都要求我们有手动造轮子的能力,所以本篇文章我会以手动实现一个promise的方式来发掘一下Promise的特点.简单版Promise首先我们应该知道Promise是通过构造函数的方式来创建的(newPromise(executor),并且为 executor 函数 传递参数:function P r o(executor)executor(resolve,reject);function)f(Auction reject。)再来说一下Promise的三种状态:pending-等待,resolve-成功,reject-失败,其中最开始为pending状态,并且一旦成功或者失败,Promise的状态便不会再改变,所以根据这点:fuMtion Proi/vu(exector)let=this;八力认g,;cxecixtoKvesoIve.bi八4(this),reject.biiad(this);缶 八ctio八 resolve)if(_tkis4status=工hk.料states=full1function reject。if(_this.iistatus=pe八力hg)_tkis.$tatus=fail1其中$status来记录P rom ise的状态,只有当p ro m ise的状态未p e n d in g时我们才会改变它的状态为fu ll或者fa il,因为我们在两个sta tu s函数中使用了 this,显然使用的是P rom ise的一些属性,所以我们要绑定resolve与re je ct中的th is为当前创建的Promise;这样我们最最最基础的Prom ise就完成了(只有头部没有四肢)Promise 高 级-.then接着,所有的P rom ise实例都可以用.th e n方法,其中.th e n的两个参数,成功的回调和失败的回调也就是我们所说的resolve和reject:fuMtioia Proi(executor)let _this=this;=pc 八 dMg;failCallBack=IA 八de fined;J:kissucceCallback=undefined;tkis.crror=八 dcFi八 ed;exec(Ator(Resob/e.bi八4(fhis),re/ect.fe(n(_this);Fcmctio八 resolve(parais)if status=pe八力hg)J:his.排 tatas=success)_tkissucces$Callback(parai)fu八cticm reject(params)if(Jhis.ftatus=八力认g。J:kis4itatus-fail1_tkis.failCallBack(parakv$)P忆。prototypehe八=fuictiofullj fail)thissuccessCallback=fullths.failCallBack=fail);/测试代W5 n e w%。3行 八 比/。八(rej)s c t T i k w c o u t Q =成功以 3(9).t h e H(r e s =coole.log(res)讲一下这里:可以看到我们增加了 failCallBack和successCallback,用来储存我们在then中回调,刚才也说过,then中可传递一个成功和一个失败的回调,当P的状态变为resolve时执行成功回调,当P的状态变为reject或者出错时则执行失败的回调,但是具体执行结果的控制权没有在这里。但是我们知道一定会调用其中的一个。executor任务成功了肯定有成功后的结果,失败了我们肯定也拿到失败的原因。所以我们可以通过params来传递这个结果或者error reason(当然这里的params也可以拆开赋给Promise实例)其实写到这里如果是面试题,基本上是通过了,也不会有人让你去完整地去实现error:用来存储,传递reject信息以及错误信息Promise 进阶我想我们最迷恋的应该就是Promise的链式调用吧,因为它的出现最最最大的意义就是使我们的callback看起来不那么hell(因为我之前讲到了 async比它更直接),那么为什么then能链式调用呢?then 一定返回了一个也具有then方法的对象我想大家应该都能猜到.then返回的也一定是一个promise,那么这里会有一个有趣的问题,就是.then中返回的到底是一个新promise的还是链式头部的调用者 9 9 9 9 9从代码上乍一看,Prom/se.theFi(.).catch(.)像是针对最初的Promise对象进行了一连串的方法链调用。然而实际上不管是then还 是catch方法调用,都返回了一个新的promise对象。简单有力地证明一下var begi八Promise=new Proiise(function.(resolve)the八PK O FV USC=beg/八POFvue.thc八(function(value)coisole.log(value);catch Promise=theiaPoiise.catcfuictioi(error)co八 so/c.e。心。r););coo(edog(begi.Proiise/=thenProm/se);/=truecon$ole.log(theiaProiise/=catchPromise);/=true显而易见promise返回的是一个新的而非调用者不过这样的话难度就来了,我们看下面代码:function Segi八()(return new Promisefresole=setTii,eout(_=resolvefirst1)ZOOO)1begii(.thei(data=cosote.log(data)return new Prom/sefresole=1).仍。nes=cok$ole.log(re$)!);我们知道最后的then中函数参数永远都不会执行,为什么说它难呢,想一下,之所以能链式调用是因为.then。执行之后返回了一个新的promise,一定注意,我说的新的 promise 是 then。所返回而不是 data=return new Promise.(这只是then的一个参数),这样问题就来了,我们从刚才的情况看,知道只有第一个.then中的状态改变时第二个then中的函数参数才会执行,放到程序上说也就是需要第一个.then中返回的promise状态改变!即:begi().theia(data=coole.log(data)return new Prokvise(resolve=setTimeout(_=-esolveCtwo、1OOO)1)=conso/eog(?es));直接从代码的角度上讲,调用了第一个.then中的函数参数中的resolve之后第一个.then。返回的promise状态也改变了,这句话有些绕,我用一张图来讲:那么问题就来了,我们如何使得P2的状态发生改变通知P1?其实这里用观察者模式是可以的,但是代价有点大,换个角度想,其实我们直接让 P2中的resolve等于P1中的resolve不就可以了?这样P 2 中调用了 resolve之后同步的P l也相当于onresolve 了,上代码:FIA八ctio八 let _jthis=this;料s tatus=peidig;_tkis.faitCallBack=undefi八 cd;_tkis.$ucce$Callback=八 deFMcd;result=八 defined;_th(s.error=undefined;setT沁=execbitoJ:hisHesob/e.bi八fhis.seject.bi八d(_tkis);)ProMi.pKototgpe.theA=fa八ctioc(fudL fail)let MwProkvi=MVJ Pemi(_=);thisucceCallback=full;this.failCallBack.=fail;协 MstxcccssDefer=八 CWPKO M,CS。仇.切 八 d(ncwProFvu);this.failPefer=MA/Proivi reject.bid(MwProi);return newProwu);Provi.prototype.reso(ve=fuiactioi(para)let _this=this;if(_tk/s.$s勿仇 ws,成 功 5 0 0).仍0八(匕4=co 八s o/c./og(?es);return,第一个.防e八成功,).theH(res=conso/eog(%s);return new Provi(fuiactioy(resolve)setTMACot(_=Kcsoke。第二个.the八 成 功SOO)1).theH(res=co 八s o/c./og(侬)return M W Prokvxfukxctioresolve,reject)setTii y/ccC第三个失败,OOO)1),协。八(%s=rescosole.log(res),rej=c。八so/eog(匕4);Promise 完善其实做到这里我们还有好多好多没有完成,比如错误处理,reject处理,catch实现.all实现,.race实现,其实原理也都差不多,(all和 race以及resolve和 reject其实返回的都是一个新的Promise),错误的传递?还有很多细节我们都没有考虑到,我这里写了一个还算是比较完善的:Function pKOMi(ex0CtOK)let _tkis=this;=pending;_this.failCalll3ack=uiadefiMd;jtkissuccessCallback=八 defined;_this.eor=认八 fined;setTiieout(_=try(exec(Ato _this.onReso(ve.bind(_this),_this.onReject.bi八,(_fhis)catch(e)_thrs.error=e;if(_this.callBackPefer&_Ms.callBackDefer.fail)_tkis.calll3ackPefer.fail(e)eke if(_tkis._catck)_ikis._catck(e)eke(throw M W Errorfn.catch)!)Povvi.prototype=constructor.Prowi,0八Rcso/vc:fukctiok(parais)if(tkis4$status=peidiig)this4istatus=success1;tkisxesolve(parais),resolve:fuMtioi(parais)let _this=this;let succeCallback=_thk.sccessCH伤 ck;if(successCallback _tkis.dcfesucccssCaHback.bM4(_this,)bdefer.fuictioia(callBack)let _this=this;let result;let defer=_this.callBacklefersuccess;if(一tkk.$sats=fail1&!_tkis.catclaEirrorFuiac)defer=_ths.callBackPefer.fail;)try(result=callBack();catch(e)result=e;defer=J:kis.callBackDefer.fail;if(result&result,八 八ceof Prom/-)丫esbdt.the八(_this.caHBackDefeKSb(ccess,_this.callBackDefer.fail);returndcfe(esbdt)boR.eject:ftmctio八(error)if(协is.$stnt s=,pc八力认g,)(thistatus=fail1;this.reject(error)卜reject:fuMtiok(error)let _tkis=this;_t is.error=error;let failCallBack=_tkis.failCall13ack;let,catch=_ihis._catcKif(failCallBack)_this.defcr(failCallBack.bikd(_thisJ error);else if(_catck)_catcM(error)eke(=throw M W Errorf八 catch prom/$e/),O),协e八:functio八(success=()=),fail)let _this=this;let resetFail=e=e;if(fail)(resetFail=fail;Jhis.catckErorFuM=true;)let HewPromise=八cw Prokvi(_=);_tkis.callBackDefer=success:ncwPronAisc.。八Rcso/ve.bi八dSewProM/use),fail:八ewPKOvuse.o八Raec七 罚 八d(newPron/usc);jthissuccessCallback=success_this.fai(Ca(lBack=re$etFail;return newProm/sebcatch:fuictioi(catchCallBack=()=)this._catch=catchCallBack./测试代码task().协皿 侬=c t m s o/c./o g :+胆)r e t u r n,第一个仍e 1)工 人。八(烟=r e t u r n M W Prokvi(re$=s e t T/m e o u t(_ =匕=。第二个 t h e ),50 0 0 ).t h e H(r e s =coole.log(ires)1)私 八(烟=r e t u r n ne w Pr o m/f f s u c,fa i l)=T而e o u t(_ =failCthen 失败:)4。6!)1).协(res=cooledog(iko)!)物 皿_=&()=return new rej)setT/meout(_=rejCproiise reject1),3000)1)1)工 e八0M e八0,协0八(_=)rej=console.log(rej);retuna rej+处理完成,!).tMenfres=co 八so/eog(%s);/故意出错co 八sole.log(ppppppp).theses=&句=coole.log(rej);/再次抛错cosole.log(oooooo).catch(e=co ns o/cog(e)1)还有一段代码是我将所有的.then全部返回调用者来实现的,即全程都用一个promise来记录状态存储任务队列,这里就不发出来了,有兴趣可以一起探讨下.有时间会再完善一下all,race,resolve.不过到时候代码结构肯定会改变,实在没啥时间,所以讲究看一下吧,欢迎交流

    注意事项

    本文(Promise由浅入深介绍.pdf)为本站会员(无***)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开