JavaScript的異步處理方案由最初讓人頭疼的callback hell,到ES6加入了抽象異步處理對象的Promise,在思想上已經(jīng)有了質(zhì)的飛躍,后來出現(xiàn)的Generator Function改成了趨向于同步的寫法,使用yield標記異步操作中需要暫停的地方,通過next()移動指針等等,但這樣做語義不太直觀,到最后終于出現(xiàn)了一種被稱為終極解決方案的方案,加入了ES7中,它就是async/await。
async/await本質(zhì)上是在操作Promise,所以還是異步
const sleep = time =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok')
}, time)
})
async function start() {
let result = await sleep(3000)
console.log(result)
}
start()
?
// async函數(shù)返回一個Promise對象
start()
.then(() => {
console.log('hello')
})
await后面的Promise對象,如果需要捕捉異常(運行結果是rejected)有如下兩種寫法:
const sleep = time =>
new Promise((resolve, reject) => {
setTimeout(() => {
reject('error')
}, time)
})
// .catch 捕捉
async function start() {
let result = await sleep(3000).catch(err => {
console.error(err)
})
}
// try/catch 語句
async function start() {
try {
let result = await sleep(3000)
console.log(result)
} catch (err) {
console.error(err)
}
}
異步循環(huán)
async function start() {
for (let i = 0; i < 5; i++) {
console.log(i)
await sleep(1000)
}
}
注意,await 只能在 async 函數(shù)中,如果用在普通函數(shù)(如forEach)中會報錯。
如果需要多個請求并發(fā)執(zhí)行,可以使用Promise.all(),用法詳見上一篇文章。
async function concurrency() {
await Promise.all(promises)
}
此外,有一篇文章介紹了一些錯誤處理和動態(tài)運算的解決方案,可以學習一下