事件循环处理的回调是否完成?

问题描述

我通过 NodeJS 的 Event Loop 文档了解到,事件循环处理的回调都是已完成的任务。

Libuv 的线程处理异步工作是否正确,当它完成时,事件循环从事件队列中拉取工作并只返回一个回调?

因为我理解的回调是工作完成后要执行的动作。

如果这个假设是正确的,事件循环什么时候可以阻塞?

此外,将事件队列和事件循环仅用于作业完成后的回调执行也是没有意义的。

我误解了什么?

解决方法

Libuv的线程处理异步工作是否正确

有些异步工作由 libuv 线程处理,有些则不是。例如,网络使用已经异步工作并且不使用或不需要线程的 OS API。 nodejs 有自己的不使用线程的定时器实现。

当它完成时,事件循环从事件队列中取出工作并返回一个回调?

当异步作业完成时,它会向事件队列中插入一个事件。当轮到该事件从事件队列中被拉出时,它将触发回调以被调用。

如果这个假设是正确的,事件循环什么时候可以阻塞?

只要前一个事件的回调仍在执行,事件循环就会被阻塞。一次处理一个事件。

此外,将事件队列和事件循环仅用于作业完成后的回调执行也是没有意义的。

我不确定您的困惑到底在哪里。当处理事件时,将调用回调并开始运行。如果正在完成的工作有进一步的异步工作,那么该回调将启动一个或多个额外的异步操作,然后它将返回到事件队列(回调将返回)。

此时,操作想要完成的工作还没有完全完成(有一些新的未完成的异步操作),但就事件循环而言,回调返回,回调本身完成,所以事件循环查找准备运行的下一个事件。

在未来的某个时刻,那些刚刚开始的异步操作将完成并在它们被调用时将一个事件插入到事件循环中,该更高级别的操作将朝着其最终目标进一步前进。因此,通过这种方式,为一些更高级别的操作服务的一系列异步操作不会在整个持续时间内阻塞事件循环,只会在沿途的一小段执行过程中,当较大的操作有机会运行其他事情时等待异步操作完成。