javascript - NodeJS 事件循环的确切处理是什么?
问题描述
我知道 NodeJS 事件循环从事件队列中收集任务并将控制权转移到任务的回调。任务完成后,任务将控制权从事件循环转移。
因此,我认为实际上返回回调是一个事件循环,它已经从任务中获得了控制权。
这是正确的想法吗?
另外,如果对Event Loop中可能发生的阻塞现象的假设是正确的,如果有一个延迟的异步任务,事件循环是否可以在等待任务返回控制权的同时处理其他任务?
或者这个假设是不正确的,所以事件循环在延迟的异步任务完成之前不起作用?
在异步等待的情况下,我想知道等待是否停止事件循环。
解决方案
您可以将事件循环视为一个实际的循环,例如:
let event_queue = [compiled_toplevel_code];
while (true) {
if (event_queue.length === 0) {
sleepUntilWokenUp();
}
if (event_queue.length > 0) {
let callback = event_queue.shift();
callback();
}
}
wheresleepUntilWokenUp()
是一个特殊函数,它暂停当前线程,直到另一个线程发送一些信号来唤醒它。异步操作(如文件系统或网络访问)由此类其他线程处理。当他们准备好执行回调时,他们会将其排入队列,然后发送适当的唤醒信号。
你可以想象setImmediate(callback)
被实现为event_queue.push(callback)
.
“将控制权从事件循环转移到回调”仅仅意味着调用回调;“将控制权返回”给事件循环只是意味着回调函数返回。
长时间运行的“异步”任务总是分解为在主线程上运行的片段,安排一些要完成的工作(通常在另一个线程上),然后返回。一旦请求的任务在后台完成,它们相应的回调就会入队。即使是“同步”调用await
也只是将函数分成两半的语法糖,以便前半部分运行到完成,而后半部分event_queue
在等待的任务完成时被推送到。
现实中的完整情况稍微复杂一些(并在 Node 文档中详细描述),有几个不同的队列用于不同种类的事物,但上面描述了一般的想法。
推荐阅读
- java - 用于提取 Representation 标签属性的 DashManifest 解析器
- asp.net-mvc - 如何将在 View 中上传的文件从 Webgrid 发布到 Controller 作为参数
- java - 什么时候使用 UsernamePasswordAuthenticationFilter?
- php - 如何针对 vscode php 中的问题检查整个文件夹?
- google-cloud-platform - 我们如何找出谷歌智能家居行动数据服务器的位置?
- react-native - DetoxRuntimeError:NSInvalidArgumentException + [UIWindowScene _keyWindowScene]:无法识别的选择器发送到类 0x12dd58db0
- docker - 来自 docker 的 Jenkins PMD 详细信息:复制源文件失败
- arrays - Dataweave - 使用重复键迭代/转换平面结构
- google-cloud-platform - GCP - Velostrata 目标云扩展
- windows-10 - 在 Windows 任务计划程序中使用可运行的 jar 创建输出文件