javascript - 为什么我需要使用 async/await 两次来使这个非阻塞?
问题描述
我有两个函数,第一个是主函数,它有 switch 语句调用第二个是异步的。如果我的第二个功能是异步的,那不是非阻塞的吗?我是否仍然必须使第一个异步以使其成为非阻塞,如果是这样,为什么?
例子
exports.funcOne = async (theParam) => { // async ??
switch (theParam) {
case 'hey':
return await funcTwo()
default:
...
}
}
const funcTwo = async () => {
await axios.get...
}
解决方案
一般来说,所有包含的函数都await
必须是async
.
如果我们想象它不存在,并且您可以在同步函数中等待异步结果,那么该规则可能更有意义。
首先,我们需要了解关于函数的一件重要事情:
它们必须运行到完成,或者换句话说:一个常规函数运行到它完成,return
并且没有其他代码可以同时运行。
如果我们可以await
在一个非异步函数内部,这意味着我们将阻止执行,直到等待的 promise 解决,因为在此期间没有其他代码可以运行。由于解决 promise 的代码也无法运行,我们创建了一个死锁。
async function
s 只运行到完成,直到达到await
. 因此,当axios.get(...)
被调用时,promise 会从它同步返回,funcTwo
停止执行,返回一个 promise 本身,因此funcOne
也停止执行(这可能是它的原因async
)。然后引擎可以继续处理其他事情,并且当底层请求完成时,承诺解决,funcTwo
继续执行解决它返回的承诺,funcOne
继续执行并解决返回的承诺。
如果我的第二个功能是异步的,那不是非阻塞的吗?
这实际上取决于您对non-blocking的定义。一般来说,执行的每一个 JS 代码都会“阻塞线程”(因为一次只能执行一个函数),但由于大多数任务非常小,你不会注意到阻塞。
Anasnyc function
也是阻塞的,只要它不停止承诺解决。然后它处于非阻塞等待状态。
异步任务(例如执行网络请求)也不会阻塞,因为它们由引擎处理(卸载到其他线程或硬件等)。
推荐阅读
- ios - Nativescript 应用程序可以在模拟器上运行,但不能在真实设备上运行。崩溃报告说 EXC_BAD_ACCESS (SIGSEGV)
- php - 循环多维数组以输出 uniq 数字列表
- google-apps-script - 如何将文件内容从 gdoc 更新到 docx
- node.js - 当我运行“节点--版本”时,我收到此消息“zsh:找不到命令:节点”
- redux - react-admin 注销时出错
- java - 我如何在 Java 的 Jackson 库中打印对象名称作为 JSON 的一部分?
- sql - 在 DAX 或 Python 中为自己的组创建显示另一列的不同计数的列
- r - R未标记的动态模型 - 对比错误
- performance - 在春季批处理作业上重新定义数据库“事务”边界
- spring-boot - 在 spring boot 项目中集成 blueocean pipeline ui