async和await是es7提供的语法,相比于es6的promise ,具有更高的代码可读性
从字面意思理解async是异步的意思,await是等待的意思,那么他们的作用就很容易看出了:
async : 声明一个函数是异步的
await : 等待一个异步函数执行完成
语法注意:await必须声明在async内部,因为async会阻断后边代码的执行,说到阻断大家不要慌,因为这里的阻断都是在一个async声明的promise函数里的阻断,不会影响整体代码的执行,async外边的代码还是照常执行
async语法的优势
async语法在处理then链的时候有优势,我们如果用promise的then嵌套可能会写出多个then链,虽然解决了回调地狱的问题,但是感觉好乱啊
用async和await实现多接口调用的代码:
function callServe1(){ return new Promise((resolve,reject)=>{ setTimeout(() => { resolve({result:"callserve1"}) }, 1000); }) } function callServe2(res){ return new Promise((resolve,reject)=>{ setTimeout(() => { resolve(res) }, 1000); }) } function callServe3(res){ return new Promise((resolve,reject)=>{ setTimeout(() => { resolve(res) }, 1000); }) } async function getAll(){ const result1 = await callServe1() const result2 = await callServe2(result1) const result3 = await callServe3(result2) console.log(result3) //{ result: 'callserve1' } } getAll()
从上面代码中看到,我们有3个接口需要依次调用,并且每一个需要上一个接口返回的参数,通过以上写法就可以以同步的语法实现这种需求,这种风格看起来很舒服,参数清晰
当然,如果只有一个接口的话,使用async其实也没啥优势,还多了一个函数的封装
处理异常:
上面的async申明的getAll方法中调用的三个异步请求并非都会执行成功,假设其中一个执行失败,执行了reject方法那么如何捕获异常并做处理
修改上面代码
function callServe1(){ return new Promise((resolve,reject)=>{ setTimeout(() => { resolve({result:"callserve1"}) }, 1000); }) } function callServe2(res){ return new Promise((resolve,reject)=>{ setTimeout(() => { // resolve(res) reject({err:"callserve2 err"}) //这个请求调用失败了,执行了reject方法 }, 1000); }) } function callServe3(res){ return new Promise((resolve,reject)=>{ setTimeout(() => { resolve(res) }, 1000); }) } async function getAll(){ try{ const result1 = await callServe1() const result2 = await callServe2(result1) const result3 = await callServe3(result2) console.log(result3) }catch(err){ console.log(err) //{ err: 'callserve2 err' } } } getAll()
可以看到,第二个请求调用失败的时候,调用了reject方法,这时候我们在getAll函数中使用try catch语法对三个await方法进行包裹,catch语法中的err可以巧妙的接收reject传递过来的参数并做相应的异常处理