Skip to content

Instantly share code, notes, and snippets.

@coodoo
Last active January 14, 2022 07:11
Show Gist options
  • Save coodoo/81f58fcd9cbb05b45077082e0bece1bc to your computer and use it in GitHub Desktop.
Save coodoo/81f58fcd9cbb05b45077082e0bece1bc to your computer and use it in GitHub Desktop.
async sample
// 前情提要:async/await 只是 Promise 的語法糖
// 只要精熟 Promise 則使用 async/await 就心無罣礙
// 範例 1 - 錯誤示範
// main 為同步執行,不會等待 forEach 內三件 async 工作完成即先結束
async function async_log(time) {
// 模擬這支 fn 經過 300ms 後才回應,因此是非同步函式
// 想像成是 fetch() 就行
return new Promise((resolve, reject) => {
setTimeout(_ => {
console.debug(`async - ${time}`)
resolve()
}, time)
})
}
function main(){
console.debug(`主線程 - 啟動`, )
// 跑到這裏啟動 forEach 內三件非同步工作,但不會等它們都完成即繼續跑下一步
;[100, 200, 300].forEach(time => async_log(time))
console.debug(`主線程 - 結束`, )
}
main()
// 範例 1 結果 - 可看到主線程先結束,之後才看到三個 async 工作的結果打印出來
// 通常這不是我們想要的行為
// 主線程 - 啟動
// 主線程 - 結束
// async - 100
// async - 200
// async - 300
// 範例 2 - 正確做法
async function async_log(time) {
// 模擬這支 fn 經過 300ms 後才回應,因此是非同步函式
// 想像成是 fetch() 就行
return new Promise((resolve, reject) => {
setTimeout(_ => {
console.debug(`async - ${time}`)
resolve()
}, time)
})
}
async function main() {
console.debug(`主線程 - 啟動`)
// 遇到 await 會等 Promise.all 內所有工作都完成後才繼續下一步
await Promise.all(
// arr.map 返還三個 Promise 交給 Promsie.all() 集體等待
// 可將 arr.map 想像為 $(elem).each(...) 都是遍歷一包 Array 做事
[100, 200, 300].map(time => async_log(time))
)
// 跑到這裏時前面 Promise.all() 內三件工作一定已完成
console.debug(`主線程 - 結束`)
}
main()
// 範例 2 結果 - 可見到主線程啟動後會停下來等內部三件 async 工作完成才結束
// 通常這是我們預期的行為
// 主線程 - 啟動
// async - 100
// async - 200
// async - 300
// 主線程 - 結束
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment