还剩6页未读,继续阅读
文本内容:
是处理异步代码的一种技术,也称为脱离回调地狱的头等舱门票Promise解决拒绝了CSDM@wly476923033编辑3承诺状态•待定状态•已解决状态•拒绝状态理解JavaScript Promis什么是承诺?通常,承诺被定义为最终可用的值的代理Promise多年来一直是JavaScript的一部分(在ES2015中标准化并引入)最近,async和await关键字(在ES2017中引入)更深入地集成和清理了JavaScript中异步函数在幕后使用Promise,因此-特别是随着当今的分布式云架构变得越Promise的语法来越普遍-了解Promise是什么以及它们如何工作比以往任何时候都更加重要!现在我们知道承诺很重要,让我们深入探讨一下如何发挥作用简要说明Promise你的代码调用了一个承诺该承诺将以所谓的待处理状态开始这是什么意思?这意味着调用函数将在Promise挂起时继续执行一旦承诺得到解决,调用函数将获取承诺所请求的数据Promise开始于待处理状态,最终以己解决状态或拒绝状态结束无论最终结果是处于已解决状态的承诺还是处于拒绝状态的承诺,都将调用回调我们定义两个单独的回调当Promise以已解决状态结束时,一个回调会处理从Promise返回的数据当Promise以拒绝状态结束时,另一个回调处理Promise返回的数据我们通过将回调函数传递给then来定义处理以已解决状态结束的Promise数据的回调函数我们通过将回调函数传递给catch来定义处理以拒绝状态结束的Promise数据的回调函数使用axios npm库的示例axios.getendpoint.thendata=resolvedPromiseCallbackFunctiondata.catch errors=rejectedPromiseCallbackFunctionerrors哪些使用JavaScript APIPromise您自己的代码和库很可能自始至终都使用Promisee值得注意的是,Promise实际上是由标准现代Web APIS使用的这里有几个也使用Promise的Web APE•服务工作者API•获取API在现代JavaScript中,您不太可能发现自己处于不使用Promise的情况-所以让我们深入研究并开始理解它们创造承诺JavaScript有一个Promise APIPromiseAPI公开了一个Promise构造函数,您可以使用以下方法对其进行初始化new Promiselet complete=trueconst hasItCompleted=new Promiseresolve,reject二〉{if complete{const completed=J Hereis thething Ibuilt resolvecompleted}else{const withReason=Still doingsomething else,reject withReason}}如图所示,我们检查complete全局常量如果complete为true,则Promise切换到已解决状态(也称为解析回调,它将Promise切换到已解决状态)否则,如果complete为false,则reject执行回调,将Promise置于拒绝状O好吧-很简单,如果我们调用回调resolve,那么我们的Promise就会切换到已解决状态,就像我们使用reject回调一样,我们的Promise会切换到拒绝状态但这给我们留下了一个问题如果我们既不调用resolve也不调用reject回调怎么办?好吧,正如您可能正在组合的那样,承诺仍处于待处理状态很简单,三个状态-两个回调函数切换到Resolved State或RejectedState,如果我们都不调用回调,那么我们只是保持在Pending State□有前途您可能遇到的一个更常见的例子是一种称为Promisifying的技术Promisifying是一种能够使用接受回调的经典JavaScript函数并让它返回一个Promise的方法const fileSystem=requirefsconst getFile=file={return new Promiseresolve,reject={fileSystem.readFilefile,err,data={if err{reject errreturn}resolvedata}}}let file=J/etc/passwd5getFilefile.then data=console,logdata.catcherr=console.errorerr在的最新版本中,您无需Node,js对许多进行手动转换模块中有一个API util函数可以为您业行此操作,前提是您所的函数具有正确的promisifying promisifying签名消费承诺new Promise现在了解了如何使用Promisifying技术创建Promise,让我们来谈谈使用Promise我们如何使用承诺又名我们如何使用承诺const isItDoneYet=newPromise/*...as above...*///...const checklfltsDone=={isItDoneYet.then ok={console,log ok}.catcherr={console,errorerr}运行将指定当承诺解决在调用中或拒绝在调用中checklfltsDone时要执行的函数isItDoneYetthencatch流畅地链接Promise如果我们想在前一个Promise返回后直接调用另一个Promise该怎么办?我们可以做到这一点,这简单地称为创建承诺链链式Promise的示例可以在Fetch API中找到,它可用于获取资源并在获取资源时对要执行的Promise链进行排队先进先出行首先,我们首先指出Fetch API是一种基于承诺的机制调用该fetch方法相当于使用定义我们自己的Promise newPromise o下面是一个将Promise流畅地链接在一起的示例const status=response=response,status=200response,status300Promise,resolveresponse:Promise,rejectnewError response.statusText constjson=response=response,jsonfetch/items.json,.thenstatus.thenjson.thendata二〉console.log Request success with json:data.catcherror=console.log,Request failed:error是运行时上兼容的最少代“node-fetch Node,js window,fetch API码不那么,我们刚刚做了什么?好吧,在上面的示例中,我们调用从域根中找到的文件fetch中获取项目列表items.json然后我们创建一个承诺链运行fetch会返回响应•响应包含status数字HTTP状态代码•响应包含statusText字符串消息,如果0K一切成功response还包含一个可调用的方法json Responsesjson方法返回一个承诺,该承诺将通过处理并转换为JSON.然后我们的链中有一个最终的Promise作为匿名回调函数传入data=console.log,Requestsuccesswithjson:data这个函数只是记录我们成功了,并且控制台记录了成功的请求json数据_“如果第一个承诺被拒绝了怎么办?”如果第一个Promise被拒绝,或者第二个Promise,或者第三个Promise-那么,无论步骤如何,我们都会自动默认为catch直观地显示在我们流畅的Promise链末尾的回调方法处理错误我们有一个承诺链,有些东西失败了,呃哦-那么会发生什么?如果Promise链中的任何内容失败并引发错误或最终将Promise的状态设置为Rejected PromiseStatecatch,则控制将直接转到Promise链中最近的语句new Promiseresolve,reject={throw newError CError5}.catch err={console,error err//ornew Promiseresolve,reject={reject JError5}.catch err=〉{console,errorerr}级联错误如果我们在a中引发错误怎么办catch好吧,检查一下-我们可以简单地附加第二个catch.第二个catch将处理错误或更具体地说是错误消自、迂迂心Onew Promiseresolve,reject={throw newErrorError}.catcherr={throw newErrorError5}.catch err={console,error err}承诺编排好的,现在我们对于单个Promise以及我们对Promise的基本理解已经很扎实了更进一步,让我们问另一个问题如果您需要同步不同的Promise-比如说从多个端点提取数据并处理所有创建并用于从这些不同端点检索结果的Promise中已解析的Promise数据-我们会怎么做?我们如何同步不同的Promise并在它们全部解决后执行某些操作?回答Promise,all Promise,all帮助我们定义一个承诺列表,并在它们全部解决后执行某些操作-它允许我们同步承诺Promise,all例子:const one=fetch/one.jsonJconst two=fetch/two.json Promise,all[one,two].thenresponse=console.log,Array ofresults:response.catcherrors=console,errorerrors通过解构,我们可以将这个例子简化为const[one,two]=[fetch/one.json,fetchJ/two.jscn5]Promise,all[one,two].then[resA,resB]=console,logresults:,resA,resBPromise.race如果我们想要从这些多个API获取所有数据,但实际上只需要从一个端点返回足够的数据来显示在我们的页面上,该怎么办?也就是说,无论如何,我们都需要解决所有的Promise,但是我们希望对第一个已解决的Promise中的数据执行某些操作,并且我们不关心哪个Promise首先得到解决为了处理第一个已解决的Promise中的数据,我们可以使用Promise,race.Promise.race当您传递给它的第一个Promise解析时运行,并且它仅运行一次附加的回调,并得到第一个Promise解析的结果例子const first=new Promiseresolve,reject={setTimeoutresolve,500,first}const second=newPromiseresolve,reject二〉{setTimeoutresolve,100,second}Promise,race[first,second],thenresult={console.logresult//second}。