setTimeout是如何在node.js中实现的
我想知道是否有人知道node.js是如何实现的。我相信我在某个地方读到过,这不是V8的一部分。我很快试图找到实现,但在源代码(大)中找不到它。但这些文件并不能完全回答我所有的问题setTimeout是如何在node.js中实现的,node.js,settimeout,Node.js,Settimeout,我想知道是否有人知道node.js是如何实现的。我相信我在某个地方读到过,这不是V8的一部分。我很快试图找到实现,但在源代码(大)中找不到它。但这些文件并不能完全回答我所有的问题 V8是否有setTimeout实现?我猜从消息来源来看,答案也是否定的 setTimeout是如何实现的?javascript、本机或两者的组合?从timers.js中,我假设以下两种情况: var Timer = process.binding('timer_wrap').Timer;` 添加多个计时器(set
- V8是否有
实现?我猜从消息来源来看,答案也是否定的setTimeout
是如何实现的?javascript、本机或两者的组合?从timers.js中,我假设以下两种情况:setTimeout
var Timer = process.binding('timer_wrap').Timer;`
- 添加多个计时器(setTimeout)时,node.js如何知道首先执行哪个?它是否将所有计时器添加到集合(已排序)?如果对其进行排序,那么查找需要执行的超时是O(1)和O(logn)以进行插入?但在timers.js中,我又看到他们使用linkedlist
- 但是,再次添加大量计时器根本不是问题
- 执行此脚本时:
var x = new Array(1000), len = x.length; /** * Returns a random integer between min and max * Using Math.round() will give you a non-uniform distribution! */ function getRandomInt (min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } var y = 0; for (var i = 0; i < len; i++) { var randomTimeout = getRandomInt(1000, 10000); console.log(i + ', ' + randomTimeout + ', ' + ++y); setTimeout(function () { console.log(arguments); }, randomTimeout, randomTimeout, y); }
你得到了一点CPU使用率,但没有那么多var x=新阵列(1000), len=x.长度; /** *返回最小值和最大值之间的随机整数 *使用Math.round()将得到非均匀分布! */ 函数getRandomInt(最小值、最大值){ 返回Math.floor(Math.random()*(max-min+1))+min; } var y=0; 对于(变量i=0;i
- 我想知道我是否在一个排序的列表中一个接一个地实现所有这些回调,以获得更好的性能
- 您已经完成了大部分工作。V8没有为
setTimeout
提供实现,因为它不是ECMAScript的一部分。您使用的函数是在timers.js中实现的,它创建了一个Timeout
对象的实例,该对象是C类的包装器
源代码中有一条注释,描述了他们是如何管理计时器的
// Because often many sockets will have the same idle timeout we will not
// use one timeout watcher per item. It is too much overhead. Instead
// we'll use a single watcher for all sockets with the same timeout value
// and a linked list. This technique is described in the libev manual:
// http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod#Be_smart_about_timeouts
这表明它使用的是一个双链接列表,在链接文章中为#4
如果没有一个请求,而是数千(百万…),那么所有
使用某种具有相同超时值的超时,然后
我们可以做得更好:
启动超时时,计算超时值并将
列表末尾超时
然后使用ev_定时器在启动时超时时触发
列表预计会触发(例如,使用技术#3)
当有活动时,从列表中删除计时器,
重新计算超时,再次将其附加到列表末尾,然后
确保更新ev_计时器(如果从开始时开始)
名单
这样,您可以在O(1)时间内管理无限数量的超时
用于启动、停止和更新计时器,费用由
主要的复杂性,并且必须使用一个恒定的超时。常数
超时可确保列表保持排序状态
Node.js是围绕异步操作而设计的,setTimeout
是其中的一个重要部分。我不想耍花招,只要用他们提供的东西就行了。相信它足够快,直到你证明在你的具体案例中它是一个瓶颈。不要陷入过早的优化
更新
所发生的事情是,基本上在顶层有一个超时字典,所以所有100ms超时都被分组在一起。每当添加新超时或触发最早的超时时,都会将其追加到列表中。这意味着最早的超时(最快触发的超时)位于列表的开头。此列表只有一个计时器,它是根据列表中第一项设置为过期之前的时间设置的
如果使用相同的超时值调用
setTimeout
1000次,它们将按照调用setTimeout
的顺序追加到列表中,无需排序。这是一个非常有效的设置。很多定时器都没有问题!
当uv循环调用轮询时,它将超时参数与所有计时器中最接近的计时器一起传递给它
[所有计时器中最近的计时器]#120 [将超时参数传递给轮询api]
#276
注意:在Windows操作系统上,逻辑几乎相同在本例中,超时总是相同的?60秒?所以你想在60秒内发生很多事情,你想弄清楚是把所有这些事情放在一起还是分别为每个事情创建一个setTimeout?不,对不起。您链接到的文档延迟了60秒。我的耽搁可能是任何事情,也可能是很多!这些只是例子。它适用于任何大于0且小于最大值的超时。但我不明白如何才能有效地超过超时。由于示例中的持续超时,列表保持排序。请参阅报价的最后一行。
RB_MIN(uv__timers, &loop->timer_handles)
timeout = 0;
if ((mode & UV_RUN_NOWAIT) == 0)
timeout = uv_backend_timeout(loop);
uv__io_poll(loop, timeout);