当前位置: 首页 > Web前端 > HTML

async-await和promise-promise.all的例子

时间:2023-03-28 16:30:35 HTML

概述Promise为js提供了并发和异步的能力,但是存在回调地狱的问题。async/await可以让一批promise以同步顺序的方式执行(这在一些接口依赖的场景是需要的),解决回调地狱的问题。promise.all可以等待一批promise任务执行完再返回,将结果集一起返回,适用于子任务互不依赖,但后续任务需要依赖多个的数据结果的场景以前的子任务。Promise/Promise.allPromise提供异步接口,配合resolve/reject,非常方便业务代码并发执行。functionpromiseReq(url){returnnewPromise((resolve,reject)=>{fetch(url).then((res)=>{resolve(res)}).catch((e)=>{reject(e)})})}//promiseReq(url1).then(res=>console.log(res)).catch(e=>console.error(e))promiseReq(url2).then(res=>console.log(res)).catch(e=>console.error(e))console.log("promise1promise2execute")Promise.all是并发执行任务的集合,等待所有任务执行完毕再返回结果一起设定。async/awaitasync顾名思义,用来定义一个异步方法,会自动将方法封装成一个Promisereturn,用return表示resolve,用throw表示reject。asyncfunctionasyncFoo(){if(Math.floor(Math.random()*10)>5){return"asyncFooresolved"}throw"asyncFoorejected"}console.日志(asyncFoo()承诺实例)asyncFoo()。then((res)=>{console.log(res)}).catch((e)=>{console.error(e)})但是在日常开发中,我们并不是单独使用async,而是配合await同步多个承诺任务。await的作用是将Promise的异步回调减少为同步方式。场景一——接口并发执行,数据结果汇总。当需要等待一批接口的数据全部返回后再继续执行后面的接口时,可以使用Promise.all来处理一批任务。它会并发执行任务集合中的Promise任务,等待所有任务执行完毕,汇总结果返回(结果数组)。比如刷新用户信息界面,1.请求基本数据2.请求订单数据3.请求邀请数据4.刷新完成,4只能在1、2、3都执行完后才能执行,很适用于Promise.all([1,2,3]).then((res)=>{4})。functionpromiseEnum(countDown){returnnewPromise((resolve,reject)=>{setTimeout(()=>{resolve("promiseEnumcountDown"+countDown)},countDown*1000)})}Promise.all([promiseEnum(1),promiseEnum(2),promiseEnum(3)]).then((values)=>{//等待123并发执行完成console.log("Promise.allvalues",values)promiseEnum(4).then((res4)=>{console.log(res4)})})场景2——接口顺序取决于执行假设有4个数据接口,后者依赖前者返回的结果继续执行.如果你使用传统的Promise,那可能是//callbackhellpromiseReq(url1).then((res1)=>{promiseReq(url2+res1).then((res2)=>{promiseReq(url3+res2).then((res3)=>{promiseReq(url4+res3).then((res4)=>{console.log("promiseReqfinished")}).catch(err=>console.error(err))}).catch(err=>console.error(err))}).catch(err=>console.error(err))}).catch(err=>console.error(err))使用async/await可以解决依赖回调问题友好,允许代码同步风格式写入和执行//使用async/await可以解决依赖回调问题友好asyncfunctionpromiseSyncReq(){letres1=awaitpromiseReq(url1)letres2=awaitpromiseReq(url2+res1)letres3=awaitpromiseReq(url3+res2)letres4=awaitpromiseReq(url4+res3)returnres4}promiseSyncReq().then((res4)=>{console.log(res4)}).catch(e=>console.log(err))async/的await的执行时间等于每个Promoise的累计总时间(执行流程本来就是序列化的,耗时自然是每个接口的累加,回调方式也是一样)。asyncfunctionawaitAllPromise(){letres1=awaitpromiseEnum(1)//阻塞等待1秒letres2=awaitpromiseEnum(2)//阻塞等待2秒letres3=awaitpromiseEnum(3)//阻塞等待waiting需要3秒letres4=awaitpromiseEnum(4)//阻塞和等待需要4秒//总的执行时间是每次Promise返回花费的累计时间[res1,res2,res3,res4]}结合async/awaitPromise/promise.all结合使用,可以灵活的实现部分任务的并发执行和部分任务的同步执行。asyncfunctionbatchExec(){console.group("batchExec")letstartTime=newDate().getTime()console.log("batchExecstart",startTime)//等候1,2,3并发执行完成letparalValues=awaitPromise.all([promiseEnum(1),promiseEnum(2),promiseEnum(3)])letparalTime=newDate().getTime()console.log("并行1,2,3完成",paralTime,(paralTime-startTime)/1000,paralValues)//再继续执行4letres4=awaitpromiseEnum(4)letendTime=newDate().getTime()console.log("batchExecend",endTime,(endTime-startTime)/1000)console.groupEnd("batchExec")返回[...paralValues,res4]}batchExec().then(res=>console.log(res)).catch(e=>console.error(e))