Thursday, June 14th, 2007

Ajax, javascript and threads : the final truth

Category: Articles, Tip

Dan Simard has been writing about threading and JavaScript and came up with his Final Truth.

Dan has an example that has a long running function that fires of an XHR request at the beginning. Will that response come back when it is done, or will it wait for the method to complete.

There are many comments comparing various browsers, and how things change when you change between synchronous and asynchronous calls.

The truth seems to be:

  • You can’t trust it to happen one way in all browsers / scenarios
  • Please split up your functions :)

Posted by Dion Almaer at 5:45 am
11 Comments

+++--
3.8 rating from 34 votes

11 Comments »

Comments feed TrackBack URI

Is this really news to anyone? If you hog the CPU, it’ll block asynchronous stuff, such as XMLHttpRequests and setTimeouts. This is also quite consistent across browsers and platforms. (The alert() just temporarily stops your scripts from hogging the CPU until you dismiss the dialog.)

As for the breaking up of functions, I’m personally getting into the habit of using callbacks for everything:

function foo () {
// does stuff…

// calls another function
sleep(10, function () {
// rest of a goes on here after 10 seconds
});
}

function sleep (secs, callback) {
// sleep returns by calling a’s callback
setTimeout(callback, secs * 1000);
}

This way, it doesn’t matter if a function does synchronous or asynchronous stuff. You give every function a callback and it will return using that callback. The callback is kind of a continuation.

One problem is that this quickly builds up a huge call stack. You can get rid of the call stack by calling a callback with setTimeout.

Comment by Tim Cooijmans — June 14, 2007

Just a minor typo…

“a long running function that fires of an XHR request”

should be:

“a long running function that fires off an XHR request”

tx

Comment by Al Jourgenson — June 14, 2007

Brendan Eich wrote an article about threads a couple of months ago…
http://weblogs.mozillazine.org/roadmap/archives/2007/02/threads_suck.html

Comment by Carlos Aguayo — June 14, 2007

c’mon guys …

for(var
nullable = null,
i = 0,
loop = 500000,
timeOut = setTimeout(function(){alert(nullable)}, 1);
i

Comment by Andrea Giammarchi — June 14, 2007

… oops …

for(var
nullable = null,
i = 0,
loop = 500000,
timeOut = setTimeout(function(){alert(nullable)}, 1);
i < loop; i++
) {
if(i + 1 === loop)
nullable = “Hello World”;
};

Comment by Andrea Giammarchi — June 14, 2007

The browser JS engine has a queue that it uses to process events (ajax responses, and setTimeouts count as events here). The queue just processes one event after another, one at a time. Each time an event is finished (which may take a lot of time as you observed), it will execute the next one. That is why you observe this behavior.

Comment by Kris Zyp — June 14, 2007

tim: JS isnt tail recursive? also have you considered using DOM synthetic events as a message passing idiom instead building up some tower of babel in callbacks..

Comment by ix — June 14, 2007

Kris, it’s not a “so perfect” answer because if You generate a modal event inside long execution code (i.e. alert(“go on, async queue”);) ajax, as intervals, starts while function execution is “blocked” :-)

for(var
nullable = null,
i = 0,
loop = 500000,
timeOut = setTimeout(function(){alert(nullable)}, 1);
i < loop; i++
) {
if(i + 1 === loop) {
// comment this alert to read Hello World
alert("nullable not yet setted");

nullable = "Hello World";
}
};

Comment by Andrea Giammarchi — June 14, 2007

You can implement a form of multi-threading in javascript, by having your code voluntarily yield execution and a scheduler object to give each thread some time.
Neil Mix wrote a library to allow this in javascript. I blogged about it at: http://blog.monstuff.com/archives/000315.html

Comment by Julien Couvreur — June 14, 2007

He probado el código de ix en FF e IE y el comportamiento es el esperado: la ejecución de la función pasada en el setTimeout sólo ocurre cuando el bloque de código que la “lanza” ha terminado. Es decir, los alert no permiten que los asincronos “expropien” al bloque de código que ejecuto el alert.

var nullable = null;
var loop = 500000;
var timeOut = setTimeout(function(){alert(nullable)}, 1);
for(var i = 0;i

Comment by joseanpg — July 30, 2007

There is a legitimate way of multi-threading in java without all these artificial constructs.

http://codediaries.blogspot.com/2009/12/real-javascript-multithreading-using.html

Comment by ireshagun — December 17, 2009

Leave a comment

You must be logged in to post a comment.