javascript - Javascript 事件队列有优先级吗?

标签 javascript jquery browser dom-events

这几天看了一些关于setTimeoutsetInterval的文档。我了解到 Javascript 是一个单线程,每次只执行一段代码。同时,如果有事件发生,将被插入事件队列并阻塞直到合适的时间。我想知道,当许多事件被阻塞等待同时执行时。这些事件是否具有不同的优先级,因此高优先级事件将在低优先级事件之前执行。或者只是一个 FIFO 队列。

setTimeout(fn1, 10);
$(document).click(fn2); //will be called at 6ms;
$.ajax({ajaxSuccess(fn3); //async request,it uses 7ms;})

 for () {
    //will run 18ms;
};

在上面的代码中,setTimeout fn1 将在 10 ms 发生,click 事件处理程序 fn2 将在 6ms 发生,ajax 回调 fn3 将在 7ms 发生,但是所有三个函数将被阻塞,直到 for 循环完成。在 18ms 时,for 循环结束,那么这些函数将按什么顺序被调用。(fn1,fn2,fn3) or (fn2,fn3,fn1)

最佳答案

为主 JavaScript 线程安排的工作是先进先出处理的。这包括来自各种异步任务的回调,例如 setTimeout 和 ajax 完成,以及事件处理程序。唯一的异常(exception)是,在主要的流行环境(浏览器和 Node)中,原生 Promise 的解析回调会跳队列(更准确地说,进入不同的更高优先级队列),参见 my answer here详细信息。

但撇开原生 promise 解析回调不谈:

but all the three functions will be blocked until the for loop finish. At 18ms, the for loop finished, so what order does these functions will be invoked. (fn1,fn2,fn3) or (fn2,fn3,fn1)

您给 setTimeout 的时间是近似值,因为当该时间到期时,JavaScript UI 线程可能正忙于做其他事情(如您所知); (新的)规范也有最短时间要求,但它的执行程度因实现而异。同样,您不能保证点击事件将在 6 毫秒时排队,或者 ajax 完成将恰好在 7 毫秒时发生。

如果该代码开始,并且浏览器精确执行了 10 毫秒,并且 click 事件恰好在 6 毫秒内排队, ajax请求恰好在 7 毫秒完成,那么顺序将是:fn2(click 处理程序),fn3(ajax 完成), fn1(setTimeout),因为这是它们排队的顺序。

但请注意,这些时间非常紧迫。实际上,我希望回调的排队顺序实际上是随机的,因为 click 的时间会有所不同,ajax 的时间也会有所不同,等等。

我认为这是一个更好的例子:

var start = +new Date();

// Queue a timed callback after 20ms
setTimeout(function() {
    display("20ms callback");
}, 20);

// Queue a timed callback after 30ms
setTimeout(function() {
    display("30ms callback");
}, 30);

// Queue a timed callback after 10ms
setTimeout(function() {
    display("10ms callback");
}, 10);

// Busy-wait 40ms
display("Start of busy-wait");
var stop = +new Date() + 40;
while (+new Date() < stop) {
    // Busy-wait
}
display("End of busy-wait");

function display(msg) {
    var p = document.createElement('p');
    var elapsed = String(+new Date() - start);
    p.innerHTML = "+" + "00000".substr(elapsed.length - 5) + elapsed + ": " + msg;
    document.body.appendChild(p);
}

输出的顺序将是两个循环消息,然后是 10 毫秒回调、20 毫秒回调和 30 毫秒回调,因为这是回调排队等待主 JavaScript 线程提供服务的顺序。例如:

+00001: Start of busy-wait
+00041: End of busy-wait
+00043: 10ms callback
+00044: 20ms callback
+00044: 30ms callback

...其中 + 数字表示脚本启动后的毫秒数。

关于javascript - Javascript 事件队列有优先级吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19743354/

相关文章:

javascript - ParseApp 从 httpRequest 保存数据

javascript - Highstock - 不规则时间间隔

javascript - 尝试使用范围 slider 来填充图表?

javascript - JavaScript VM如何实现对象属性访问?是哈希表吗?

javascript - 需要从代码隐藏中调用 Javascript 方法

javascript - Chart.js 在折线图上绘制两个 json 数据集

javascript - 如何使用jquery获取输入是否有焦点

javascript - 标题 JQuery Mobile 中的导航栏

java - 如何确定我的网站/网页在用户桌面上是否处于 Activity 状态

javascript - 我有分割屏幕的 javascript 代码,但是,如何从 Flex 应用程序运行它?