从我看到的情况来看,如果Node中的事件需要"长时间"调度,Node会创建某种"事件队列",并且会尽快逐个触发它们.
这个队列可以有多长时间?
虽然这似乎是一个简单的问题,但它实际上是一个相当复杂的问题; 不幸的是,没有任何人可以给你的简单数字.
第一:在这里任何事情都没有真正起作用.所有事件都以相同的方式发送,无论事情是否"花费很长时间".换句话说,所有事件都通过"队列".
第二:没有单一的队列.有许多地方可以将不同类型的事件分发到JS中.(以下假设你知道什么是滴答.)
有些东西(或你使用的库)传递给你process.nextTick()
.它们在当前刻度结束时被调用,直到nextTick队列为空.
有些东西(或你使用的库)传递给你setImmediate()
.它们在下一个刻度开始时调用.(这意味着nextTick
任务可以无限期地向当前刻度添加内容,防止其他操作发生,而setImmediate
任务只能将事物添加到队列中以进行下一次刻度.)
I/O事件被处理libuv通过epoll
/ kqueue
/ IOCP在Linux/Mac的/ Windows的分别.当操作系统通知libuv发生了I/O时,它又调用JS中的相应处理程序.事件循环的给定标记可以处理零个或多个I/O事件; 如果刻度需要很长时间,I/O事件将在操作系统队列中排队.
操作系统发送的信号.
在单独的线程上执行的本机代码(C/C++)可以调用JS函数.这通常通过libuv工作队列完成.
由于工作可能排队的地方很多,因此要回答"当前排队的项目数量"并不容易,更不用说这些队列的绝对限制了.从本质上讲,任务队列大小的硬限制是可用RAM.
在实践中,您的应用将:
点击V8堆约束
对于I/O,最大化允许的打开文件描述符的数量.
......在任何队列的大小变得有问题之前.
如果您只是对您的应用程序是否处于高负荷感兴趣,可能会感兴趣 - 它会对事件循环的每个滴答进行计时,以确定您的应用程序是否花费了不寻常的时间来处理每个滴答(可能表示您的任务队列非常大).