async 不一定是異步的
雖然 async 這個詞本身表示異步(asynchronous的縮寫),但 async 函數(shù)本身并不是異步的。是的,你沒有看錯,這個頂著異步名號的家伙,其實是個同步函數(shù),真正的“異步”在它的肚子里。如果 async 函數(shù)的函數(shù)體里執(zhí)行的全都是同步操作,那么它就和普通的函數(shù)沒什么區(qū)別,只有當其中執(zhí)行到異步的操作的時候,配合 await 才會發(fā)揮出真正的威力。
const asyncFunc = async () => {
console.log('called')
const result = await Promise.resolve('async')
console.log(result)
}
asyncFunc()
.then(res => console.log('then'))
.catch(err => console.log(err))
console.log('sync')
- 在函數(shù)定義的最前面添加 async 表示這是個 async 函數(shù)。
- awiat 只能在 async 函數(shù)內部使用。
- async 函數(shù)本身是同步的,所以 "called" 會先打出來;直到遇到第一個 await ,函數(shù)先返回,后面的流程全都視為異步。所以 "async" 會在 "sync" 之后打出。
- await 后面通常接一個異步操作,待執(zhí)行完成后返回結果,再往下執(zhí)行。當然 await 后面也可以接一些原始類型,此時這就相當于是一個同步操作。但這并不影響 async 函數(shù)會在這之前先返回。
- async 函數(shù)的調用和普通函數(shù)一樣。
- async 函數(shù)總是返回一個 Promise,如果函數(shù)內 return 語句返回的不是 Promise,則會被包裝秤一個立即 resolve 的 Promise對象。
- async 函數(shù)在遇到第一個 awiat 時會先返回一次,交還程序的控制權給到父級,函數(shù)內的后續(xù)流程會繼續(xù)異步執(zhí)行,直到完成或出錯,才正式返回一個 Promise。
async 函數(shù)的錯誤處理
async 函數(shù)的錯誤處理機制其實和 Promise 差不多,只不過一些細節(jié)上需要留意一下。
async 函數(shù)里如果出現(xiàn)有 Promise 被 reject 的情況,無論代碼中是否有 return ,函數(shù)會立即返回一個被 reject 的 Promise,后續(xù)代碼不會執(zhí)行。如果希望異步操作出錯不影響后續(xù)的邏輯,可以把異步操作嵌套在 try...catch 里,如果異步操作本身就是 Promise,也可以用 Promise 的 catch() 來處理。