如何知道Javascript Engine事件队列中排队事件的大致位置?

时间:2018-04-19 10:33:04

标签: javascript javascript-events event-queue

假设我们正在生成一系列事件并将其排入可用的Javascript引擎的事件队列中。是否有方法或任何行业最佳实践来估计特定事件的排名?

非常感谢有关此主题的任何见解。

1 个答案:

答案 0 :(得分:0)

没有标准的方法来以编程方式查看事件循环的队列。了解事件在该队列中的位置的唯一方法是知道它相对于其他事件的添加时间,并了解事件循环中的事件类型。

在现代环境中,JavaScript有两种"稍后执行此操作"排队:主事件循环(包含" macrotasks"),以及在每个主循环任务结束时运行的第二个循环,用于任何"微任务"由那个macrotask安排。在浏览器上还有第三种东西requestAnimationFrame(RAF),它与事件循环分开(同时仍与它们协调)。

您熟悉的大多数事件处理程序称为" macrotasks"在主事件循环中。 setTimeout,DOM事件等。

承诺完成处理程序被称为"微任务"紧接在他们排队的macrotask之后(所以他们在下一个macrotask之前运行,如果有的话,即使它先排队)。

当浏览器即将重新绘制时,在macrotasks之间调用RAF回调,即使下一个macrotask在requestAnimationFrame回调之前排队也是如此。

示例:



function run() {
  requestAnimationFrame(function() {
    log("RAF 1");
  });
  function log(msg) {
    var p = document.createElement("pre");
    p.appendChild(document.createTextNode(msg));
    document.body.appendChild(p);
  }
  setTimeout(function() {
    log("timeout 1");
    Promise.resolve().then(function() {
      log("resolution 2 -- before timeout 2");
    });
  }, 0);
  setTimeout(function() {
    log("timeout 2");
    requestAnimationFrame(function() {
      log("RAF 2");
    });
  }, 0);
  setTimeout(function() {
    log("timeout 3");
    requestAnimationFrame(function() {
      log("RAF 3");
    });
  }, 0);
  Promise.resolve().then(function() {
    log("resolution 1");
  });
}
function tick() {
  document.body.innerHTML = "";
  run();
  setTimeout(tick, Math.random() * 800);
}
tick();

pre {
  margin-top: 0;
  margin-bottom: 0;
}




如果你观看的时间足够长,你会注意到虽然超时和承诺分辨率总是以相同的顺序,但是RAF回调在它们之间的不同时间发生(通常在结束时,但并非总是如此)。

还要注意承诺解决方案(微任务)如何在下一个宏任务之前运行。