简单理一下async/await
刚好看到一篇文章,有写到async/await的,于是就自己也简单记录一下。
我们都知道是用Promise能很好的解决回调地狱的问题,但是如果处理流程比较复杂的话,那么整段代码将充斥着then,语义化不明显,于是就有async/await可以代替是用
前面添加了async的函数再执行后都会自动返回一个Promise对象:
function foo(){ return 'lsc' } console.log(foo()) // 'lsc'
添加asycn后
async function foo(){ return 'lsc' //Promise.resolve('lsc') } console.log(foo()) //Promise foo()
async函数中是用await,那么await这里的代码就会变成同步的了,意思就是说只有等await后面的Promise执行完成得到结果才会继续下去,await就是等待。如下:
function timeout(){ return new Promise(resolve=>{ setTimeout(()=>{ console.log(1) resolve() },1000) }) } //不加async和await是2、1 加了是1、2 async function foo(){ await timeout() console.log(2) } foo()
使用场景:
加入有这样一个是用场景:需要先请求a链接,等返回信息之后,再请求b链接的另外一个资源。下面代码展示的事是用fetch来实现这样的需求,fetch被定义再window对象中,它返回的事一个Promise对象。
fetch('https://www.baidu.com').then(response=>{ console.log(response) return fetch('https://baidu1.com') }).then(response=>{ console.log(response) }).catch(error=>{ console.log(error) })
虽然上述代码可以实现这个需求,但语义化不明显,代码不能很好的标识执行程序。基于这个原因,ES8引入了async/await,这个JavaScript异步编程的一个重大改进,提供了再补阻塞主线程的情况下是用同步代码实现异步访问资源的能力,并且使得代码逻辑更加清晰。
async function foo(){ try{ let response1=await fetch('https://www.baidu.com') console.log(response1) let response2=await fetch('https://www.baidu1.com') console.log(response2) } catch(err){ console.error(err) } } foo()
通过上面代码,会发现整个异步处理的逻辑都是使用同步代码的方式来实现的,而且还支持try catch来捕获异常。
注意:
1、await只能在async标记的函数内部使用,单独使用会触发Syntax error
2、await后面需要跟异步操作,不然就没有意义,而且await后面的Promise对象不必写then,因为await的作用之一就是获取后面Promise对象成功状态传递出来的参数
async/await的缺陷
await关键字会阻塞其后的代码,知道promise完成,就像执行同步操作一样。它确定可以允许其他任务在此期间继续运行,但代码被阻塞。
这意味着代码可能会因为大量await的promises相继发生而变慢。每个await都会等待前一个完成,而你实际想要的是所有的这些promises同事开始处理
(可以通过将Promise对象存储在变量中来同事开始它们,然后等待它们全部执行完毕。)