JavaScript and Threading

Monday, January 8, 2007

Someone asked me if the "asynchronous" in AJAX means we should be worried about thread safety and global variables in client-side script. This is an interesting question to ponder.

A search of the ECMAScript language specification returns zero hits for the word "thread". JavaScript, like C++, appears to leave threads as an implementation detail. There are no keywords or intrinsic ECMAScript objects available to manage threads, or to provide for thread synchronization.

I find it strange that there are articles like "Implementing Mutual Exclusion For AJAX" claiming to control threads. Some of these articles assert that integer assignment in JavaScript is an atomic operation. I've yet to see documentation that proves this assertion and I'm wary of this claim given the number of software layers between the scripting runtime and the hardware.

I don't think we are in a position to even worry about concurrent threads in script. With no mechanism to control threads, we have to trust our browsers to "do the right thing". IE7 appears to use a single thread for executing script code in a page. Based on experiments with the native debugger and Winspector, the thread appears to be a message-pumping UI thread. I'd have to assume that other browsers (at least on Windows) also follow a single threaded model for simplicity. I have no proof, so any insight readers can provide would be appreciated.

In trying to confirm this behavior, I came across a 2003 post by Eric Lippert: "What are "threading models", and what threading model do the script engines use?". Here is a juicy excerpt:

* When the script engine is in a state where it cannot possibly call an ActiveX object -- for instance, if it has just been created and has not started running code, or if it is just about to be shut down -- then the script engine really is free threaded, but who cares? It can't do much in this state.
* When the script engine is initialized -- when the script engine host has started the process of passing code and object model state to the engine -- the script engine morphs into an apartment threaded object. All calls to the script engine must be on the initializing thread until the script engine is shut down again.

Eric then muddies the water in a later comment:

It's very difficult to do true multi-threading inside IE. However, there are clever things you can do with the setTimeout method. I've also been thinking that it might be interesting to describe setTimeout from a continuation-passing-style perspective.

It doesn't appear that Eric ever followed up on this comment, unfortunately.

But what about the A in AJAX? Assuming xmlHttp is a native object it is free to use any number of background threads to free up the browser's UI. When xmlHttp raises an event, however, that call must marshal to the thread responsible for executing script.

I do wonder what this single threaded model means for the future. As the amount of script code for AJAX and WPF/E grows, this model has the potential of being a bottleneck.

Manu Temmerman-Uyttenbroeck Monday, January 8, 2007
Recently I had a few problems (and still have) with ajax / javascript. I'm using the Anthem framework. Until now the javascript setTimeout function is helping me out in most cases.
I still don't understand 100%, but I just knows it helps :)
You can read this post:
Rick Strahl Monday, January 8, 2007
Well you can certainly get yourself into a bind with AJAX callbacks in this 'single threaded' model. If you have callbacks that set global variables you have the same situation you have in a multithreaded environment with static or shared instance data even though you're just simulating it with single STA style marshalled UI threads <s>.
Scott Monday, January 8, 2007
Rick: I can certainly imagine another problem where 2 AJAX calls (a & b) go out, but come back in reverse order (b then a). I imagine this trips up some code.

I've yet to get events raised on a different thread. Perhaps this is something special in IE7? Either that or my experiemental code is too simple.

I have a feeling that setTimeout results in some sort of WM_SOMETHING message that always routes processing back to the UI thread.

Anthony Mills Tuesday, January 9, 2007
All evidence I have found points to that browsers use a single-threaded model. Not only that, it works in the same thread as UI updates. It seems that the inner loop of a browser looks like:

Run initialization code
While Running
- Display state of current DOM
- Wait for event
- Run code in event handler (JS and native)
End While

Some things seem to short-circuit this. For example, if you alert() in the middle of JS, IE will update the browser view to the current DOM even though you're in the middle of a JS call. This was probably done because otherwise it would seem too weird.
Comments are closed.

My Pluralsight Courses

K.Scott Allen OdeToCode by K. Scott Allen
What JavaScript Developers Should Know About ECMAScript 2015
The Podcast!