基本原理
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