简体   繁体   中英

Is Javascript event queue a simple FIFO or not?

Take a look at this example:

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

Is it guarantied that B will immediately run after A ?
Is it possible that browser add another task in the queue between A and B ?

note: none of A or B functions are adding any new tasks to event loop.

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

Are there any difference in the order of execution of callbacks in case 1 vs case 2 ?

Is it guarantied that B will immediately run after A?

Not immediately , no, but it's guaranteed that B will run after A . Full details in the spec , but in short, this is specifically addressed in the timer initialization steps which say in part:

Wait until any invocations of this algorithm that had the same method context, that started before this one, and whose timeout is equal to or less than this one's, have completed.

Optionally, wait a further user-agent defined length of time.

Queue the task task .

...where task is the task of calling the callback you gave setTimeout .

The task queue is required to be run in order, and so A will run before B on a compliant browser.

Note that this is guaranteed because they were queued by the same method context (see the spec for details of what that means).

Is it possible that browser add another task in the queue between A and B?

Yes. The browser can be multi-threaded and queue a task for some other thing (a message from a web worker, etc.) in-between queuing the tasks for A and B . In that case, you'd see A run, then your handler for the other task (processing the message from the web worker or whatever), then B .

They will always fire in the correct order, A then B . However, they may not fire consecutively.

In fact, the specification says that timeout callbacks are not even placed on the execution queue until the timer has elapsed, which may be subject to additional delays - the timeout you specify is only a minimum amount of time to wait.

JavaScript uses an event queue for timers.

在此输入图像描述

Also see this article: Excellent and still actual article about timers in JavaScript by John Resig.

Yep, if yo try this:

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

You will see that the function C has an infinite loop, so it is never the function is executed B. This is because the functions passed to the task/events list and run as these end. This is in relation to the event list The setTimeout have a particular way of working. but, if you asking.

On the other hand if you ask if that case ever to be executed first , followed by B , the answer is no guarantee ue happen because they are not the only events that can be running .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM