fn()
。進一步說,async函數徹底能夠看做多個異步操做,包裝成的一個Promise對象,而await命令就是then方法的語法糖promise
async函數返回一個Promise對象,可使用then方法添加回調函數。當函數執行的時候,一旦遇到await就會先返回,等到異步操做完成,在接着執行函數體後面的語句異步
async function fn(){ console.log(4) let f1 = await Promise.resolve(1) console.log(f1) // 1 let f2 = await Promise.resolve(2) return f2 } fn().then(res=>{ console.log(res) // 2 }) console.log(3) // 4 3 1 2
上面代碼中,函數前面的async關鍵字,表示函數內部有異步操做。調用該函數時,會當即返回一個Promise對象。async
function timeout(ms){ return new Promise((resolve)=>{ setTimeout(resolve,ms) }) } async function fn(value,ms){ await timeout(ms) console.log(value) } fn('haha',3000)
上面代碼會在3秒後輸出
haha
函數
async函數有多種使用形式。this
// 函數聲明 async function fn(){} // 函數表達式 let fn1 = async function(){} // 對象的方法 let obj = {async foo(){}} obj.foo().then(()=>console.log(111)) // 111 // class 的方法 class fn2{ constructor(name){ this.name = name; } async getName(){ return this.name } } let name = new fn2('小明'); name.getName().then(res=>console.log(res)) // 小明
async函數返回一個Pormise對象。
async函數內部return語句返回的值,會成爲then
方法回調函數的參數code
let fn = async function(){ return 111 } fn().then(res=>{console.log(res)}) // 111
上面代碼,函數
fn
返回的值,會被then
放回回調函數接收到orm
async內部拋出錯誤,會致使返回的Promise對象變爲reject狀態。拋出的錯誤對象會被catch方法回調函數接收到。對象
let fn = async function(){ throw new Error('出錯了') } fn().catch(error=>{ console.log(error); // Error: 出錯了 })
async函數返回的Promise對象,碧璽等到內部全部await命令後面的Promise對象執行完,纔會發生狀態改變,除非遇到return
語句或者拋出錯誤。也就是說,只有asunc函數內部的異步操做執行完,纔會執行then方法指定的回調函數。字符串
let fn = async function(){ await new Promise((resolve)=>{ setTimeout(resolve,3000) }) await new Promise((resolve)=>{ setTimeout(resolve,3000) }) return 1 } fn().then(res=>{ console.log(res); })
上面代碼,
then
回調函數會在6秒以後輸出res
get
正常狀況下,await命令後面是一個Promise對象,返回該對象的結果。若是不是Promise對象,就直接返回對應的值
let fn = async function(){ // 等同於 // return 1 return await 1 } fn().then(res=>{ console.log(res); // 1 })
上面代碼中,await命令的參數是數值1,這是等同於
return 1
let fn = async ()=>{ await Promise.reject('出錯了') } fn().catch(error=>{console.log(error)}) // 出錯了
注意:上面代碼中,await語句前面沒有
return
,可是reject
方法的參數依然傳入了catch方法的回調函數。這裏若是在await前面加上return,效果是同樣的
注意:任何一個await語句後面的Promise對象變爲reject,那麼整個async函數都會中斷執行
有時,咱們但願即便前一個異步操做失敗,也不要中斷後面的異步操做。這時能夠將第一個await放在try...catch結構裏面,這樣無論這個異步操做是否成功,第二個await都會執行
let fn = async ()=>{ try{ await Promise.reject('出錯了') }catch(error){ console.log(error) } return 1 } fn().then(res=>console.log(res)) // 1
另外一種寫法
let fn = async ()=>{ await Promise.reject('出錯了').catch(error=>{ console.log(error) }) return 1 } fn().then(res=>console.log(res)) // 1
若是await後面的異步操做出錯,那麼等同於async函數返回的 Promise 對象被reject。
let fn = async ()=>{ await Promise.reject('出錯了') return 1 } fn() .then(res=>console.log(res)) .catch(error=>{ console.log(error) // 出錯了 })
上面代碼中,函數fn執行後,await後面的Promise對象拋出了一個錯誤對象,致使catca方法的回調函數被調用。
防止出錯的方法,也是將其放在try...catch
代碼塊中
let fn = async ()=>{ try{ await Promise.reject('出錯了') }catch(error){ console.log(error); } return 1 } fn() .then(res=>console.log(res)) // 1
若是有多個await命令,能夠統一放在try...catch
中