async/await 是异步还是同步?

问题描述 投票:0回答:2

我实际上是第一次深入了解 asyc/await 部分,所以我很难理解它。

我知道 async wait 用于使函数以异步方式运行,但是如何,因为根据定义,“await”关键字会暂停函数的执行,直到承诺得到解决,然后执行中的剩余代码功能。这不是同步行为吗,因为事情正在按应有的顺序执行?

如果我有什么地方错了,请随时帮助我摆脱困惑。

javascript asynchronous async-await
2个回答
7
投票

都不是。

async
await
关键字是管理承诺的工具。

Promise 是一种管理异步代码的工具。

如果将函数标记为

async
那么:

  • 其正常返回值被替换为解析为其正常返回值的 Promise。
  • 你可以在里面使用
    await

如果您在 Promise 的左侧使用

await
,则包含函数将进入休眠状态,直到 Promise 解决。异步函数外部的执行将在休眠时继续(即不会停止)。

这使您可以使用看起来适用于同步代码的语法来处理异步代码。

它不会使同步操作异步,反之亦然。


0
投票

这不是同步行为吗,因为事情正在按应有的顺序执行?

这取决于我们如何定义术语同步和异步。它们在 JavaScript 世界中具有非常特定的含义。首先,这些术语是“相对”术语,即它们需要一个上下文:我们可以说代码是相对于当前正在运行的某些代码同步执行的。如果我们说代码是相对于当前任务异步执行的,那么这意味着它在调用堆栈为空之前不会执行,并且它是由某个作业队列中的作业触发的。 但是当一段异步代码开始运行时,我们开始以该执行为参考点进行讨论,我们可以再次谈论它的某些部分是同步执行的,而其他部分可能仍然是异步执行的,再次涉及a中的作业作业队列。 简而言之,当当前执行的代码(参考点)和我们标记为“异步”的代码执行之间,调用堆栈为空时,我们就谈到异步。

await

关键字会停止函数的执行,直到承诺得到解决

我不会称之为“停止”。对于函数的调用者来说,函数已同步执行到(并包括)

await

 表达式。然后,该函数向调用者
返回

(承诺):调用者的代码执行将像在任何其他函数调用之后一样继续执行。没有真正的
停止

。相反,异步函数的执行上下文将被保存以供以后继续。

同样,作为异步函数同步执行的一部分,await运算符评估其操作数,如果它不是 thenable(如 Promise),则将其包装到 Promise 中。然后函数返回。因此,从调用者的角度来看,操作数也是同步计算的。
当 Promise 解决时,作业将被放入微任务队列(Promise 作业队列)中。当调用代码(同步代码)执行运行直到调用堆栈为空时,JavaScript 引擎将检查其队列。如果它发现微任务队列中已经存在该 Promise 作业,它将执行它。这将恢复保存的异步函数的执行上下文,并且代码可以从该点开始继续执行。

如果遇到另一个

await
,则计算其操作数,这次异步函数返回到作业处理程序(而不是您的代码),使调用堆栈为空。在某些时候,等待的承诺可能会解决,这将再次将作业放入微任务队列中......等等。

© www.soinside.com 2019 - 2024. All rights reserved.