setTimeout如何在Node.JS中工作?
我想,一旦它被执行,它就在队列中,但在队列中是否有任何保证它会在X毫秒后精确调用? 还是会把其他繁重的任务放在队列上延迟呢?
setTimeout的语义与Web浏览器中的大致相同:超时参数是执行前等待的最小数量的ms,而不是保证。 此外,传递0,非数字或负数将导致它等待最小数量的ms。 在Node中,这是1ms,但是在浏览器中它可以高达50ms。
原因是JavaScript没有抢占JavaScript。 考虑这个例子:
setTimeout(function () { console.log('boo') }, 100) var end = Date.now() + 5000 while (Date.now() < end) ; console.log('imma let you finish but blocking the event loop is the best bug of all TIME')
这里的stream程是:
- 安排100ms的超时时间。
- 忙等待5000ms。
- 返回到事件循环。 检查挂起的定时器并执行。
如果情况并非如此,那么你可能会有一点JavaScript“中断”另一个。 我们必须设置互斥锁和信号等,以防止这样的代码极难推理:
var a = 100; setTimeout(function () { a = 0; }, 0); var b = a; // 100 or 0?
Node的JavaScript执行的单线程使其比其他大多数并发风格更简单。 当然,权衡是因为程序中一个不好的部分可能会以无限循环来阻止整个事情。
这是一个更好的恶魔战斗比复杂的先发制人? 那要看。
非阻塞的思想是循环迭代很快。 所以迭代每个滴答时间应该足够短一段时间,setTimeout将精确到合理的精度(closures可能<100毫秒左右)。
理论上虽然你是对的。 如果我写一个应用程序并阻止勾号,那么setTimeouts将被延迟。 所以要回答你的问题,谁可以保证setTimeouts按时执行? 通过编写无阻塞的代码,您可以控制几乎任何合理程度的准确度。
只要javascript在代码执行(不包括networking工作者等)方面是“单线程的”,那将会一直发生。 单线程本质在大多数情况下是一个巨大的简化,但是要求非阻塞式的成语是成功的。
在浏览器或节点中尝试使用此代码,您将看到无法保证准确性,相反,setTimeout将会很晚:
var start = Date.now(); // expecting something close to 500 setTimeout(function(){ console.log(Date.now() - start); }, 500); // fiddle with the number of iterations depending on how quick your machine is for(var i=0; i<5000000; ++i){}
除非解释器优化循环(它不在chrome上),否则你会得到成千上万的东西。 删除循环,你会看到它的鼻子上500 …
确保代码执行的唯一方法是将setTimeout逻辑放在不同的进程中。
使用subprocess模块来产生一个新的node.js程序,它执行你的逻辑并通过某种stream(也许是tcp)将数据传递给那个进程。
这样,即使在你的主进程中运行了一些长的阻塞代码,你的subprocess已经自己启动了,并且在一个新进程和一个新线程中放置了一个setTimeout,并在你期望的时候运行。
进一步的复杂性是在一个硬件级别,你有更多的线程运行,然后进程,因此上下文切换会导致(很小)的延迟,从你的预期时间。 这应该是微不足道的,如果重要的话,你需要认真考虑你想要做什么,为什么你需要这样的准确性,什么样的实时替代硬件可用来完成这项工作。
一般来说,使用subprocess并将多个节点应用程序作为单独的进程与负载平衡器或共享数据存储(如redis)一起运行对于扩展代码非常重要。
setTimeout(callback,t)
用于在至lesst毫秒后运行callback。 实际的延迟取决于许多外部因素,如操作系统计时器粒度和系统负载。
所以有可能在设定的时间后稍微调用它,但以前不会调用它。
计时器不能超过24.8天。
setTimeout是一种Thread ,它持有给定时间的操作并执行。
setTimeout(function,time_in_mills);
在这里第一个参数应该是一个函数types,例如,如果你想在3秒后打印你的名字,你的代码应该是下面的东西。
setTimeout(function(){console.log('your name')},3000);
要记住的关键是,你想通过使用setTimeout方法做什么,做一个函数。如果你想调用一些其他方法通过parting一些参数,你的代码应该看起来像下面,
setTimeout(function(){yourOtherMethod(parameter);},3000);
开心nodejs编码:)