JavaScript的异步处理方案由最初让人头疼的callback hell,到ES6加入了抽象异步处理对象的Promise,在思想上已经有了质的飞跃,后来出现的Generator Function改成了趋向于同步的写法,使用yield标记异步操作中需要暂停的地方,通过next()移动指针等等,但这样做语义不太直观,到最后终于出现了一种被称为终极解决方案的方案,加入了ES7中,它就是async/await。
async/await本质上是在操作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函数返回一个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)
}
}
异步循环
async function start() {
for (let i = 0; i < 5; i++) {
console.log(i)
await sleep(1000)
}
}
注意,await 只能在 async 函数中,如果用在普通函数(如forEach)中会报错。
如果需要多个请求并发执行,可以使用Promise.all(),用法详见上一篇文章。
async function concurrency() {
await Promise.all(promises)
}
此外,有一篇文章介绍了一些错误处理和动态运算的解决方案,可以学习一下