setTimeout如何在Node.JS中工作?

| 我猜想它一旦执行就在队列中,但是在队列中有没有保证它会在X毫秒后准确调用?还是队列中其他较高任务会延迟它?     
已邀请:
setTimeout的语义与Web浏览器中的语义大致相同:超时arg是执行之前等待的最小毫秒数,而不是保证。此外,传递0,一个非数字或负数将使它等待最小ms数。在Node中,这是1毫秒,但是在浏览器中,它可能长达50毫秒。 这样做的原因是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\')
这里的流程是: 安排100ms的超时时间。 繁忙等待5000毫秒。 返回事件循环。检查未决的计时器并执行。 如果不是这种情况,那么您可以使用另一种JavaScript \“ interrupt \”。我们必须设置互斥体和信号量等,以防止此类代码极难推理:
var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?
Node \的JavaScript执行的单线程性使其比大多数其他并发样式更容易使用。当然,要权衡的是程序行为不当的部分可能会无限循环地阻塞整个过程。 这比抢占的复杂性更好吗?那要看。     
非阻塞的想法是循环迭代很快。因此,对每个刻度进行迭代应花费足够短的时间,以使setTimeout可以精确到合理的精度(偏差可能小于100毫秒左右)。 从理论上讲,虽然您是对的。如果我编写了一个应用程序并阻止了滴答声,那么setTimeouts将被延迟。因此,要回答您的问题,谁可以确保setTimeouts按时执行?您可以通过编写非阻塞代码来控制准确度,几乎可以达到任何合理的准确度。 只要javascript在代码执行方面是“单线程的”(不包括网络工作者等),这种情况就总是会发生。在大多数情况下,单线程性质是一个极大的简化,但是要求非阻塞用法才能成功。 在浏览器或节点中尝试该代码,您将发现无法保证准确性,相反,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逻辑置于不同的进程中。 使用子进程模块生成一个新的node.js程序,该程序执行逻辑并将数据通过某种流(也许是tcp)传递给该进程。 这样,即使在您的主进程中正在运行一些长时间阻塞的代码,您的子进程也已经自行启动并将setTimeout放置在新进程和新线程中,并因此将在您期望的时间运行。 进一步的复杂性是在硬件级别上,在该级别上,您正在运行的线程数量要多于进程数量,因此上下文切换将导致(非常小的)延迟与预期的时间。这应该可以忽略不计,并且如果有问题,您需要认真考虑您的尝试,为什么需要这种准确性以及可以使用哪种实时替代硬件来代替这项工作。 通常,使用子进程并将多个节点应用程序作为单独的进程与负载平衡器或共享数据存储(例如redis)一起运行对于扩展代码很重要。     
setTimeout(callback,t)
至少在t毫秒后用于运行回调。实际延迟取决于许多外部因素,例如OS计时器粒度和系统负载。 因此,有可能在设置的时间之后稍稍调用它,但永远不会在之前调用它。   计时器的时间不能超过24.8天。     
setTimeout
是一种线程,它在给定的时间内保存一个操作并执行。
setTimeout(function,time_in_mills);
在这里,第一个参数应该是函数类型;例如,如果您想在3秒钟后打印您的姓名,则您的代码应如下所示。
setTimeout(function(){console.log(\'your name\')},3000);
要记住的关键是,无论您想使用
setTimeout
方法做什么,都可以在函数内完成。如果要通过解析一些参数来调用其他方法,则代码应如下所示:
setTimeout(function(){yourOtherMethod(parameter);},3000);
    

要回复问题请先登录注册