哪个先激活,之前创建的setTimeout()或更早安排的?

时间:2015-12-22 01:02:59

标签: javascript node.js

考虑以下事项..

var timeoutA = setTimeout(functionA, 200);

// CPU intensive task blocks the event loop for ~50 ms

var timeoutB = setTimeout(functionB, 100);

// CPU intensive task blocks the event loop for ~200 ms

// Now what?

所以我们的情况是有两个未完成的超时,两个都计划在过去的某个时刻点火。一个(timeoutA)是两个中的,因为它是先创建的,但另一个(timeoutB)被安排更早,即使它是第二次创建的。

哪个超时将"赢得"并首先执行其功能? (特别是在node.js v5中,但也有兴趣了解其他引擎)。

关于js计时器的执行顺序存在几个现有问题,但没有解决其创建顺序和计划执行顺序冲突的情况。这些问题涉及创建计时器并计划以相同顺序运行的实例:

2 个答案:

答案 0 :(得分:1)

好的,所以在运行一些测试之后,好像预定的订单优先。也就是说,在上面的示例中,make_shared始终先执行。

timeoutB

输出..

Scheduling timeoutA for 200 ms in future
Blocked till 50 ms
Scheduling timeoutB for 100 ms in future
Blocked till 250 ms
Timeout B run after 250 ms
Timeout A run after 250 ms

这适用于所有已经出现的js引擎,具体来说:

  • node.js(v0.12.4,v4.1.1,v5.0.0)
  • iojs(v1.8.1,v2.0.2,v3.0.0)
  • Sarafi(v9.0.2)
  • Chrome(v47.0.2526)

答案 1 :(得分:1)

我通过异步执行理解JS的方法如下。

有一个事件哈希,其中列出了所有事件异步任务(如设置超时,ajax请求,点击处理程序等等)。然后有一个队列,其中包含所有被解雇的'事件(准备好运行的回调,设置时间到期的超时,单击已经听过的事件......)。最后有一个运行循环,通过做两件事来不断地管理这两个数据结构:首先,它反复检查事件哈希中的事件是否需要放入队列(就像setTimeout或者时间已经过去一样) ajax请求已解决)。其次,如果队列有一个需要调用的回调,它将出队并在每个循环中调用队列中的下一个函数。

现在深入了解您的问题,事件以什么顺序进入此队列?

基本上,当调用setTimeout时,会将事件添加到具有特定“时间签名”的哈希值,即当前时间+传递给超时参数的ms量。现在,当运行循环到达将向队列添加内容的点时,如果它看到多个setTimeouts准备入队,它将排队具有较早的时间签名的那个'首先,然后还将另一个事件和任何其他已准备好的事件排入队列(例如,如果在上述两个时间签名之间发生了点击事件,那么事件'回调将在两者之间发生两个setTimeouts)。所以,回到上面的例子,即使我们确实在你调用的这两个setTimeout函数的中间有一个cpu密集型任务,第二个setTimeout带有' time签名' + 150ms小于第一个+ 200ms,因此对setTimeout的第二次调用将使其队列中的回调更高,并且将首先调用它。