javascript - 事件循环处理的回调是否完成?
问题描述
我通过 NodeJS 的事件循环文档了解到,事件循环处理的回调是已完成的任务。
Libuv的线程处理异步工作是否正确,当它完成时,事件循环从事件队列中拉出工作并返回一个回调?
因为我理解的回调是工作完成后要执行的动作。
如果这个假设是正确的,事件循环什么时候可以阻塞?
此外,事件队列和事件循环仅用于作业完成后的回调执行是没有意义的。
我有什么误解?
解决方案
Libuv的线程处理异步工作是否正确
有些异步工作由 libuv 线程处理,有些则不是。例如,网络使用的操作系统 API 已经异步工作并且不使用或不需要线程。nodejs 有自己的不使用线程的计时器实现。
完成后,事件循环从事件队列中提取工作并返回一个回调?
当异步作业完成时,它会将一个事件插入到事件队列中。当轮到该事件从事件队列中被拉出时,它将触发回调以被调用。
如果这个假设是正确的,事件循环什么时候可以阻塞?
只要前一个事件的回调仍在执行,事件循环就会被阻塞。一次处理一个事件。
此外,事件队列和事件循环仅用于作业完成后的回调执行是没有意义的。
我不确定您的困惑到底在哪里。处理事件后,将调用回调并开始运行。如果正在完成的工作还有进一步的异步工作,那么该回调将启动一个或多个额外的异步操作,然后它将返回到事件队列(回调将返回)。
此时,操作想要完成的工作尚未完全完成(有一些新的未完成的异步操作),但就事件循环而言,回调返回并且回调本身已完成,因此事件循环找到准备运行下一个事件。
在未来的某个时间点,那些刚刚开始的异步操作将完成,并在它们被调用时将一个事件插入事件循环,更高级别的操作将朝着其最终目标取得进一步进展。因此,通过这种方式,为某些更高级别操作服务的一系列异步操作不会在整个持续时间内阻塞事件循环,只会在沿途的一小段执行过程中,当更大的操作有机会运行其他事情时等待异步操作完成。
推荐阅读
- javascript - 尝试使用 reduce 对数组中对象的属性求和:未定义?
- python - 从另一个 docker 容器连接到 docker 容器中的 mysql 服务器
- flutter - 没有为静态变量定义 getter,也没有为类中声明的方法定义 getter
- python - Pyspark:使用 Python 从 Spark 2.4 连接到 MS SQL Server 2017 时没有合适的驱动程序错误
- c++ - Visual Studio 2017 15.9.13 不能使用自动 C++ 模板
- windows - 使用 ConvertTo-SecureString 问题:我可以使用 powershell 重置多个 ADUC 密码吗?
- javascript - 啁啾 wasm DOMException
- nosql - 使用 Fakeit 生成数据
- node.js - 未经同意屏幕使用 Drive API 将文件上传到 Google Drive
- javascript - 如何改变满足一定条件的数组的两个连续值?