Strange behavior in Firefox handling asynchronous, synchronous

Tuan Ngo
2 min readFeb 22, 2019

Background:
In 2017, an email from our bridge engineer in Japan brought my attention since an incident is reported for almost one month but no one in the engineer team in the Korea center could figure out why.

One reason why the investigation get stuck is that there are so many possible causes which a bloated Javascript single page application usually encounter.

The problem is too interesting that it triggers my itchy. Then, I started to look into it and found something interesting.

Now you can do exercise a bit with a simple Javascript assignment as follows:

Start an asynchronous call and then the other synchronous in the same call stack. Then put log to watch out execution steps.

The prototype code is as follows:

var URL = 'fake-api.js';function callAsync() {
console.log('callAsync:start');
$.ajax({
url: URL,
async: true
}).done(function () {
console.log('callAsync:done');
}).fail(function () {
console.log('callAsync:fail');
})
console.log('callAsync:end');
}
function callSync() {
console.log('callSync:start');
$.ajax({
url: URL,
async: false
}).done(function () {
console.log('callSync:done');
}).fail(function () {
console.log('callSync:fail');
})
console.log('callSync:end');
}
function execute() {
console.log('execute:start');
callAsync();
callSync();
console.log('execute:end');
}
execute();

Note: The code is also available in https://github.com/tnngo2/async-firefox-prototype.

Then compare the result in Chrome, Firefox and IE (also):

Chrome 72.0.3626.109:

Firefox 65.0.1:

IE 11:

Do you see any difference between two logs above? Here is the problem:

How come does the synchronous call in Firefox triggers the callback of previous asynchronous even before its callback.

In this situation, Chrome and IE implement more sensible behavior that synchronous call and its callback should not be interfered by any other instruction. The JS VM should wait for the synchronous response come back and execute its callback before executing any other waiting instructions in Message Queue.

If you do not familiar with how Javascript VM do the concurrency, you can refer to the “Concurrency modal and Event Loop” document in MDN.

P/S: The result is still possible to reproduce in the latest Firefox version.

--

--