【问题标题】:Is Javascript event queue a simple FIFO or not?Javascript 事件队列是不是一个简单的 FIFO?
【发布时间】:2016-02-09 16:16:54
【问题描述】:

看看这个例子:

function A() { console.log('A'); }
function B() { console.log('B'); }
// and then i setTimeout(fn, 0) both of them
setTimeout(A, 0);
setTimeout(B, 0);

是否保证B 会在A 之后立即运行?
浏览器是否有可能在AB 之间的队列中添加另一个任务?

注意:AB 函数都没有向事件循环添加任何新任务。

var callbacks = [];
// then add a bunch of callbacks ... (none adds events to event queue)
//case 1:
callbacks.forEach(cb => setTimeout(cb,0))
//case 2:
setTimeout(function() {
   callbacks.forEach(cb => cb());
},0);

case 1case 2 中回调的执行顺序有什么不同吗?

【问题讨论】:

  • 简单回答:不,不能保证。因为除了 JS 引擎之外,还有很多其他的东西都用到了这个队列。
  • 是否同时使用?是否有可能来自DOM 的事件在 js 的一部分运行时被排队? (js不是单线程吗?长时间运行的js脚本会停止冻结浏览器?)

标签: javascript settimeout


【解决方案1】:

是否保证B会在A之后立即运行?

不是立即,不,但可以保证B 将在A 之后运行。完整的细节in the spec,但简而言之,这在timer initialization steps 中专门解决了部分内容:

等到该算法的任何调用都完成了

(可选)等待用户代理定义的时间长度。

排队任务任务

...其中task是调用你给setTimeout的回调的任务。

任务队列需要按顺序运行,因此在兼容的浏览器上A 将在B 之前运行。

请注意,这是有保证的,因为它们是按相同的方法上下文排队的(请参阅规范以了解其含义的详细信息)。

浏览器是否有可能在 A 和 B 之间的队列中添加另一个任务?

是的。浏览器可以是多线程的,并在为AB 排队任务之间为其他事情(来自网络工作者的消息等)排队一个任务。在这种情况下,您会看到 A 运行,然后是您的处理程序用于其他任务(处理来自网络工作者的消息或其他),然后是 B

【讨论】:

    【解决方案2】:

    它们总是以正确的顺序开火,A 然后B。但是,它们可能不会连续触发。

    事实上,the specification says 在计时器结束之前,甚至不会将超时回调放在执行队列中,这可能会受到额外的延迟 - 您指定的超时只是 最小 量等待的时间。

    【讨论】:

    • 是否有可能在AB 之间运行另一个任务说C
    • 是的,这是可能的。虽然不太可能,但引擎本身是多线程的,并且可以在A 被添加到队列和B 被添加到队列之间接收另一个要排队的事件。
    【解决方案3】:

    JavaScript 为计时器使用事件队列。

    另见这篇文章: Excellent and still actual article about timers in JavaScript by John Resig.

    【讨论】:

      【解决方案4】:

      是的,如果你试试这个:

      function A() { console.log('A'); }
      function B() { console.log('B'); }
      function C() { while(1) { console.log('C'); } }
      // and then i setTimeout(fn, 0) both of them
      setTimeout(A, 0);
      setTimeout(C, 0);
      setTimeout(B, 0);
      

      你会看到函数 C 有一个无限循环,所以永远不会执行函数 B。 这是因为函数传递给任务/事件列表并作为这些结束运行。这与事件列表有关 setTimeout 具有特定的工作方式。 但是,如果你问的话。

      另一方面,如果您询问是否先执行该案例,然后执行 B,答案是不能保证会发生,因为它们不是唯一可以运行的事件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-16
        • 1970-01-01
        • 1970-01-01
        • 2013-11-15
        相关资源
        最近更新 更多