async await 全解
2021-05-09 本文已影响0人
littleyu
前端似乎对 Promise 不满
优点
Async/Await替代Promise的6个理由
但是,除了更简洁意外,其他理由似乎都不是很有说服力。
为什么需要 async ?
看起来非常多余,await 所在的函数就是 async ,不是吗?
已经搜索发现,在 await 之前,已经有人实现了 await 函数,她的函数是这样的:
function fn () {
const result = await(xxx())
}
所以如果 JS 一发布这个语法,那么这个人就不能继续运行她的代码了,所以为了避免这种情况,JS 只能强行加一个 async 关键词(虽然没有任何实质意义)作区分(用心良苦,为了兼容旧代码里普通函数的await),继而保证大家都能使用。
如何优雅的处理错误
const ajax = function () {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject({ status: 403, message: '无权限' })
}, 2000)
})
}
const errHandler = err => {
console.log(err)
throw err
}
async function fn () {
const res = await ajax().catch(errHandler)
console.log('继续运行接下来的代码')
}
fn()
上述的 errHandler 之所以最后 throw err 是因为,如果直接 return 一个值,会被直接赋值给 res,所以直接使用 throw err 还能打断程序进程,防止下面的代码继续运行。
缺点
具有传染性
console.log(1)
await console.log(2)
console.log(3)
console.log(3) 变成异步任务了,
Promise 同样具有传染性,then 里面都是异步,除非直接写在 下面。
谁没有传染性:回调。
天生串行
await ajax1()
await ajax2()
await ajax3()
await ajax4()
其中有一个陷阱关于循环的陷阱
const ajax1 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax1')
resolve()
}, 2000)
})
const ajax2 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax2')
resolve()
}, 2000)
})
const ajax3 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax3')
resolve()
}, 2000)
})
const fn = async () => {
const array = [ajax1, ajax2, ajax3];
for (let i = 0; i < array.length; i++) {
await array[i]()
}
}
fn()
用普通的 for 循环是正常的
const ajax1 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax1')
resolve()
}, 2000)
})
const ajax2 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax2')
resolve()
}, 2000)
})
const ajax3 = () => new Promise(resolve => {
setTimeout(() => {
console.log('ajax3')
resolve()
}, 2000)
})
const fn2 = async () => {
const array = [ajax1, ajax2, ajax3];
array.map(async ajax => await ajax())
}
fn2()
当用 map 遍历的时候,就会同时运行三个 ajax