基本原理
async / await 本质上是 generator 的语法糖,与 generator 相比,多了以下几个特性:
- 内置执行器,无需手动执行 next() 方法
- await 后面的函数可以是 promise 对象也可以是普通 function,而 yield 关键字后面必须得是 thunk 函数或 promise 对象
例子
将 add() 视为一个需要运行很长时间的函数
js 默认为异步非阻塞
const sleep = () => new Promise((res, rej) => setTimeout(res, 1000))
async function add(a, b) {
await sleep()
console.log( a + b )
}
function mul(a, b) {
console.log( a * b )
}
function main() {
let a = 1, b = 2
add(a, b)
mul(a, b)
}
main()
结果,先执行了 mul(),后执行了 add():
2
3
希望先执行 add(),后执行 mul() ,方式 1:callback
const sleep = () => new Promise((res, rej) => setTimeout(res, 1000))
async function add(a, b, callback) {
await sleep()
console.log( a + b )
callback(a, b)
}
function mul(a, b) {
console.log( a * b )
}
function main() {
let a = 1, b = 2
add(a, b, mul)
}
main()
结果,先执行了 add(),后执行了 mul():
3
2
希望先执行 add(),后执行 mul() ,方式 2:promise
async 使得后面的 function 始终返回一个 promise
const sleep = () => new Promise((res, rej) => setTimeout(res, 1000))
async function add(a, b) {
await sleep()
console.log( a + b )
}
function mul(a, b) {
console.log( a * b )
}
function main() {
let a = 1, b = 2
add(a, b).then(function (fulfilled) { // 当promise 状态变成 fulfilled 时,调用此函数
mul(a, b)
})
}
main()
结果,先执行了 add(),后执行了 mul():
3
2
希望先执行 add(),后执行 mul() ,方式 3:await
const sleep = () => new Promise((res, rej) => setTimeout(res, 1000))
async function add(a, b) {
await sleep()
console.log( a + b )
}
async function mul(a, b) {
console.log( a * b )
}
async function main() {
let a = 1, b = 2
await add(a, b)
await mul(a, b)
}
main()
结果,先执行了 add(),后执行了 mul():
3
2
参考
https://github.com/frontend9/fe9-interview/issues/6
https://wiki.jikexueyuan.com/project/node-lessons/promise.html