1. async和await最關鍵的用途是以同步的寫法實現了異步調用,是對Generator異步方法的簡化和改進。使用Generator實現異步的缺點如下:
- 得有一個任務執行器來自動調用next()
yield
命令后面只能是 Thunk 函數或 Promise 對象,Thunk函數只接受一個參數,然后返回一個把回調函數作為參數的函數(很繞,不直觀)
2.函數前使用async修飾符時不管函數內出不出錯都會返回一個Promise對象;
3.返回的Promise對象是由誰決定的?
- 如果函數體內的語句沒有錯誤,則會返回一個fulfilled狀態的Promise,否則返回一個rejected狀態的Promise
- 如果有await語句,只要其中一個await后面的語句出錯,則返回一個rejected狀態的Promise,后面的語句不會被執行。
function test(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject('出錯了') },500) }) } async function f() { await test(); console.log('上面的await返回了rejected狀態') await Promise.resolve(456); } f().then(v => console.log(v)).catch(e => console.log('有錯誤'))
在上面的代碼中f函數語句內await test()下面的語句都不會被執行。
- 如果返回fulfilled狀態的Promise對象,可以使用return xxx語句指定值,不然默認為undefined
function test(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('出錯了') },500) }) } async function f() { await test(); await Promise.resolve(456); return '返回值' } f().then(v => console.log(v)).catch(e => console.log('有錯誤'))
控制台輸出“返回值”,如果注釋掉f函數里面的return語句,控制台將輸出undefined
4.await后面的代碼會返回什么?
await后面的代碼可以是同步代碼,也可以是異步代碼,相應的情況如下:
//同步函數 function syncFun(){ } //異步函數 function asyncFun(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(456) },1000) }) } async function f() { let a=await 123; //a為123 let b=await syncFun(); //b為undefined let c=await asyncFun() //c為456 return '返回值' } f().then(v => console.log(v)).catch(e => console.log(e))
如果await后面是一個函數(不管是同步還是異步的),只要有錯誤或者異步返回的狀態是rejected,則馬上中止此await下面的語句,並返回一個rejected狀態的Promise