Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
757 views
in Technique[技术] by (71.8m points)

jquery - Does Javascript event queue have priority?

These days, I have read some documents about setTimeout and setInterval. I have learned that the Javascript is a single thread which will only execute one piece of code per time. At the same time, if there is a event happens, it will be pushed into the event queue and block until appropriate time. I want to know, when many events are blocked waiting to execute at the same time. Do these events have different priorities, so the high priority event will execute before the low ones. Or just a FIFO queue.

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

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

In the above code, the setTimeout fn1 will happen at 10 ms,click event handler fn2 will at 6ms, ajax callback fn3 will at 7ms, 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)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Work scheduled for the main JavaScript thread is processed FIFO. This includes callbacks from various async tasks, such as setTimeout and ajax completions, and event handlers. The only exception is that in the main popular environments (browsers and Node), the resolution callback of a native Promise jumps the queue (more accurately, goes in a different higher-priority queue), see my answer here for details on that.

But leaving aside native promise resolution callbacks:

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)

The time you give setTimeout is approximate, because when that time comes due the JavaScript UI thread may be busy doing something else (as you know); there's also a minimum time required by the (newish) spec, but the degree to which it's enforced varies by implementation. Similarly, you can't guarantee that the click event will be queued at 6ms, or that the ajax completion will occur at exactly 7ms.

If that code started, and the browser did the 10ms precisely, and the click event was queued exactly 6ms in, and the ajax request completed at exactly 7ms, then the order would be: fn2 (the click handler), fn3 (the ajax completion), fn1 (the setTimeout), because that's the order in which they'd be queued.

But note that these are extremely tight timings. In practice, I expect the order the callbacks were queued would be effectively random, because the timing of the click would vary, the timing of the ajax would vary, etc.

I think this is a better example:

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);
}

The order of output will be the two loop messages followed by the 10ms callback, 20ms callback, and 30ms callback, because that's the order in which the callbacks are queued for servicing by the main JavaScript thread. For instance:

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

...where the + numbers indicate milliseconds since the script started.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...