async 函数本身会返回一个 Promise
async await 函数处理异步回调比 Promise 的 then 函数更优雅、简洁,所以我比较喜欢前者。
回到正题,本文在这里聊一聊 async await 函数的执行顺序问题。本人曾经对此非常疑惑。
用伪代码理解 async await
其实 async 函数本身会返回一个 Promise。
其实 async、await 就是 Promise 和 generator 函数的语法糖。
为了帮助理解,举个例子:
下面这个 async function speak 函数,如果使用 Promise + then 函数的形式是这样的:(可以这样粗浅的理解)
async 函数:
js
async function speak() {
const res = await new Promise(resolve => {
setTimeout(() => {
resolve('11')
}, 1000)
})
return res
}转换为 Promise + then 函数形式:
js
function speak() {
return new Promise(o_resolve => {
new Promise(i_resolve => {
setTimeout(() => {
i_resolve('11')
}, 1000)
}).then(value => {
// 伪代码
// 将 return 的返回值作为成功值(resolve value),更改 Promise 的状态。
// const res = (return 的返回值)
o_resolve(res)
})
})
}实际的一个例子
执行 main 函数,过了多久会打印 res1 和 res2 呢?
js
main()
async function main() {
// 如果 speak1 和 speak2 前面不加 await,那么打印的是两个未知状态的 Promise
// const res1 = speak1()
// const res2 = speak2()
const res1 = await speak1()
const res2 = await speak2()
console.log(res1, res2)
}
async function speak1() {
const res = await new Promise(resolve => {
setTimeout(() => {
resolve('1')
}, 1000)
})
return res
}
async function speak2() {
const res = await new Promise(resolve => {
setTimeout(() => {
resolve('2')
}, 1000)
})
return res
}在上面的代码中,两秒后正确的打印 1、2
如果在 speak1()、speak2() 函数前面没有加上 await 关键字,那么打印的将是两个未知状态的 Promise。
结论
虽然 async await 很好,但是 async await 处理错误也可能会导致写很多 try catch 代码,导致不那么优雅、简洁。如果真的不想看到有那么多 try catch,可以考虑使用 await-to-js 库。
async 函数本身会返回一个 Promise,所以如果想要等这个函数执行完后再执行后面的代码,它的前面必须加上 await。