Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding how alert() impacts browser event loop

I'm considering adding an alert() to our Javascript utility assert function.

We're an ajax-heavy application, and the way our framework (Ext) implements ajax by polling for the ajax response with setInterval instead of waiting for readystate==4, causes all of our ajax callbacks to execute in a setInterval stack context -- and an exception/assert blowing out of it usually fails silently.

How does a low-level alert() impact the browser event loop? The messagebox by definition must allow the win32 event loop to pump (to respond to the mbox button). Does that mean other browser events, like future setIntervals generated by our framework, resize events, etc, are going to fire? Can this cause trouble for me?

IIRC: you can use Firefox2 and Firefox3.5 to see the difference I'm talking about.

alert('1');
setTimeout(function(){alert('2');}, 10);
alert('3');

Firefox3.5 shows 1-3-2. Firefox2[1] shows 1-2&3 (2 and 3 stacked on top of each other simultaneously). We can replicate 1-2&3 in IE8 with a win32 mbox launched from ActiveX as well, instead of an alert, which wreaked havoc on us back in the day, and I want to make sure we don't go down that path again.

Can anyone point me to specific low level resources that explain this behavior, what the expected behavior is here, and what exactly is going on at a low level, including why the behavior changed across Firefox versions?

[1] you can replicate this on Spoon.net which I can't get working right now. I just reproduced it in a VM with Firefox 2.0.0.20.

like image 241
Dustin Getz Avatar asked Jun 07 '11 17:06

Dustin Getz


People also ask

How does a browser event loop work?

The Event Loop has one simple job — to monitor the Call Stack and the Callback Queue. If the Call Stack is empty, the Event Loop will take the first event from the queue and will push it to the Call Stack, which effectively runs it. Such an iteration is called a tick in the Event Loop.

How does event loop decides which function to run next?

The Event Loop takes the timer with the shortest wait time and compares it with the Event Loop's current time. If the wait time has elapsed, then the timer's callback is queued to be called once the call stack is empty. Node. js has different types of timers: setTimeout() and setInterval() .

Does browser have event loop?

With a queueing mechanism in place, high priority tasks can be executed in a timely manner. This is the browser Event Loop. The common task is called MacroTask and the high priority task is called MicroTask. MacroTask includes: setTimeout , setInterval , requestAnimationFrame , Ajax, fetch, script tag code.

What is the precedence in event loop?

The event loop is actually composed of one or more event queues. In each queue, events are handled in a FIFO order. It's up to the browser to decide how many queues to have and what form of prioritisation to give them. There's no Javascript interface to individual event queues or to send events to a particular queue.


1 Answers

First, timers in javascript are not very precise. Intervals smaller than 30ms might be considered all the same, and implementations vary. Don't rely on any implicit ordering.

An alert() will always halt the event loop. If an event or timer fires during the alert, they will be queued and called after the event loop resumes (the alert box is closed).

Take this example:

var hello = document.getElementById('hello')

setTimeout(function(){
  hello.style.backgroundColor = 'lime'
}, 5000)

alert('Stop!')

setTimeout(function(){
  hello.innerHTML = 'collaborate'
}, 20)

setTimeout(function(){
  hello.innerHTML = 'listen'
}, 1000)

There are two possible outcomes:

  1. You close the alert box in under 5 seconds. The two timers that follow will be set and fire at specified intervals. You can see that the event loop is halted because regardless of how long you wait to close the alert, "listen" will always take 1s to execute.

  2. You take longer than 5 seconds to close the alert. The first interval (bgColor) will have passed, so it executes immediately, followed by the two timers being set and called.

http://jsbin.com/iheyi4/edit

As for intervals, while the event loop is stopped it also "stops time", so in this case:

i = 0

setInterval(function(){
  document.getElementById('n').innerHTML = ++i
}, 1000)

setTimeout(function(){
  alert('stop')
}, 5500)

Regardless of how long you take to close the alert, the next number will always be 6 - the setInterval won't fire multiple times.

http://jsbin.com/urizo6/edit

like image 118
Ricardo Tomasi Avatar answered Oct 19 '22 20:10

Ricardo Tomasi