背景

最近在回头看nfd项目 的源码,看到了使用async和await的js代码,因此想了解一下代码运行的机制。

一个例子

function SicBo() {
 return new Promise((resolve, reject) => {
   console.log("开始摇")
   setTimeout(() => {
     let n = parseInt(Math.random() * 6 + 1, 10)
     resolve(n)
  }, 1000)
})
}

上述代码的执行过程如下:

  • 立即执行 console.log("开始摇") —— ✅ 马上输出。

  • 启动一个“1秒后执行的任务” —— 通过 setTimeout(...) 注册了一个回调,1 秒后执行。

  • 返回一个 Promise 对象,这个 Promise 会在 1 秒后变成“完成状态”并给出点数。

如果直接调用这个函数:

function test() {
 const result = SicBo()
 console.log('骰子结果:', result)
}
test()

调用输出如下:

开始摇
骰子结果: Promise { <pending> }

显然并不是我们想要的结果

异步函数的一般调用:

SicBo().then(result => {
 console.log('骰子结果:', result)
})

这种写法最大的弊端是会产生回调地狱,即调用多个异步函数产生嵌套,导致代码可读性变差。

异步函数的async和await调用:

async function test() {
 const result = await SicBo()
 console.log('骰子结果:', result)
}
test()

调用输出如下:

开始摇
(等待1秒)
骰子结果: 3

异步函数外部调用

async function demo() {
 console.log('A. 开始')
 await SicBo()
 console.log('B. 结束')
}

demo()
console.log('C. 我是其他逻辑')

调用输出如下:

A. 开始
开始摇
C. 我是其他逻辑
(等待1秒)
B. 结束