js中的async,await与Promise

最近在研究arco design代码,翻看到axios的response的拦截器时,被一段代码搞困惑了,代码如下

axios.interceptors.response.use((response: AxiosResponse<HttpResponse>) => {const res = response.data;// if the custom code is not 20000, it is judged as an error.if (res.code !== 20000) {...省略代码若干return Promise.reject(new Error(res.msg || 'Error'));}return res},(error) => {} 

重点就在这段代码里的return返回的数据,他返回了不同类型的数据,一个是返回了Promise对象,一个返回了普通数据,那我应该如何统一处理这个返回结果呢。

平常都是用的Promise对象,对异步处理都是标准的

new Promise().then().catch()

如果拦截器里返回的都是Promise对象,我也不会困惑了,但是这个拦截器可能返回异步对象,可能返回普通数据,总不能给普通数据也用then和catch吧。

本着绝不放过一个困惑宗旨,探究一番。

一 js中的异步方案

同步与异步

同步就是cpu执行代码时候一条一条执行,按顺序同步着执行。

异步就是cpu同时执行不同的功能代码,比如边播放视频,边放声音。

编程语言中的异步方案

各种编程语言都有异步解决方案,无非是协程,线程,进程。

js是单线程,采用协程方案实现并发。

同步事件是一个容易理解的事情,但异步事件却是一个反直觉的事情,所以各编程语言在语法层面上前仆后继,想要消灭这种反直觉的事情。

js也不例外,异步方案经历了好次多迭代。

Promise 对象

Promise对象是一个异步对象,经典使用方式如下: 假设定义了一个请求异步对象,网络请求总会是个耗时的事情,不可能只干等着请求结果,不去处理别的事情了。

var request = new Promise((ok,bad)=>{//一段时间后//如果成功ok("ok")//如果失败bad("error")
}) 

这就是一个常见的异步对象定义,那如何使用?

request.then(ok=>{console.log(ok)
}).catch(err=>{console.log(err)
}) 

异步对象都有then,catch,finally三个api函数,分别用来处理不同结果,then处理正确的结果,catch处理异常结果,finally不管结果如何都会调用。

注意,这三个函数都是回调函数,这段代码执行后不会停留,也就是异步执行then,catch,和finally的代码。什么时候request有结果了就通知对应的回调函数调用。

这种语法比js最开始的纯回调函数实现的异步方案已经是一个进步了,纯回调函数实现的异步方案有可能造成恐怖的回调地狱现象。

promise要是碰上回调地狱只能说,略好。

request1.then(ok=>{request2.then(ok=>{request3.then(ok=>{...})})
}) 

async await

js中的异步方案还是要看async和await,这是一种用同步思维编写异步代码的方案。当然是最容易使用的一种方案。

使用规则:

1.async用于修饰定义函数,会对返回值进行promise包装。

 var asyncFun = async function(){return "this async ok"}var asyncFun2 = async function(){throw("this is async error")}var asyncFun3 = async function(){return Promise.resolve("this is promise")}console.log("async返回结果:")console.log(asyncFun())console.log(asyncFun2())console.log(asyncFun3()) //返回结果如下// async返回结果:// Promise {<fulfilled>: 'this async ok'}// Promise {<rejected>: 'this is async error'}// Promise {<pending>} 

2.await 只能用在被async修饰的函数中。

 var asyncFun3 =function(){var msg = await "this is a" //此处有语法错误return msg} 

3.await 后可以跟任何数据,包括promise对象,和非promise对象。如果后边跟着promise对象会对promise的执行结果做处理,如果是resolve则直接返回,如果是reject则抛出异常throw。

 var async4 = async function(){var msg = await asyncFun()console.log("await ok result:",msg)try{ await asyncFun2()}catch(err){console.log("await err result:",err)}}async4()//打印结果// await ok result: this async ok// await err result: this is async error 

结论

从规则中可以看出,async可以更容易的生成promise对象,而await则可以用同步的方法去使用异步方法,async是promise的打包,await则是promise的拆包。

await后如果跟非promis对象,其实效果和没有await一样,所以最开始的困惑这里就能解开了,await可以对后边跟着的结果做动态处理,处理的结果都一样,都是普通js类型的数据或者抛出异常。

最后

为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

猜你喜欢

转载自blog.csdn.net/web22050702/article/details/129824243