Andrey
Andrey

Reputation: 21285

Is JavaScript multithreaded?

Here's my issue - I need to dynamically download several scripts using jQuery.getScript() and execute certain JavaScript code after all the scripts were loaded, so my plan was to do something like this:

function GetScripts(scripts, callback)
{
  var len = scripts.length
  for (var i in scripts)
  {
    jQuery.getScript(scripts[i], function() 
    {
      len --;
      // executing callback function if this is the last script that loaded
      if (len == 0)
        callback()  
    })
  }
}

This will only work reliably if we assume that script.onload events for each script fire and execute sequentially and synchronously, so there would never be a situation when two or more of the event handlers would pass check for (len == 0) and execute callback method.

So my question - is that assumption correct and if not, what's the way to achieve what I am trying to do?

Upvotes: 64

Views: 55378

Answers (9)

balaji ap
balaji ap

Reputation: 66

JS in general is single threaded. However HTML5 Web workers introduce multi-threading. Read more at http://www.html5rocks.com/en/tutorials/workers/basics/

Upvotes: 4

bucabay
bucabay

Reputation: 5295

To be clear, the browser JS implementation is not multithreaded.

The language, JS, can be multi-threaded.

The question does not apply here however.

What applies is that getScript() is asynchronous (returns immediately and get's queued), however, the browser will execute DOM attached <script> content sequentially so your dependent JS code will see them loaded sequentially. This is a browser feature and not dependent on the JS threading or the getScript() call.

If getScript() retrieved scripts with xmlHTTPRequest, setTimeout(), websockets or any other async call then your scripts would not be guaranteed to execute in order. However, your callback would still get called after all scripts execute since the execution context of your 'len' variable is in a closure which persists it's context through asynchronous invocations of your function.

Upvotes: 7

Ibolit
Ibolit

Reputation: 9720

You can probably get some kind of multithreadedness if you create a number of frames in an HTML document, and run a script in each of them, each calling a function in the main frame that should make sense of the results of those functions.

Upvotes: 0

dan_nl
dan_nl

Reputation: 4446

Thought it might be interesting to try this out with a "forced", delayed script delivery ...

  1. added two available scripts from google
  2. added delayjs.php as the 2nd array element. delayjs.php sleeps for 5 seconds before delivering an empty js object.
  3. added a callback that "verifies" the existence of the expected objects from the script files.
  4. added a few js commands that are executed on the line after the GetScripts() call, to "test" sequential js commands.

The result with the script load is as expected; the callback is triggered only after the last script has loaded. What surprised me was that the js commands that followed the GetScripts() call triggered without the need to wait for the last script to load. I was under the impression that no js commands would be executed while the browser was waiting on a js script to load ...

var scripts = [];
scripts.push('http://ajax.googleapis.com/ajax/libs/prototype/1.6.1.0/prototype.js');
scripts.push('http://localhost/delayjs.php');
scripts.push('http://ajax.googleapis.com/ajax/libs/scriptaculous/1.8.3/scriptaculous.js');


function logem() {
    console.log(typeof Prototype);
    console.log(typeof Scriptaculous);
    console.log(typeof delayedjs);
}

GetScripts( scripts, logem );

console.log('Try to do something before GetScripts finishes.\n');
$('#testdiv').text('test content');

<?php

sleep(5);
echo 'var delayedjs = {};';

Upvotes: 1

Hannoun Yassir
Hannoun Yassir

Reputation: 21182

No, all the browsers give you only one thread for JavaScript.

Upvotes: 11

Ivan Nevostruev
Ivan Nevostruev

Reputation: 28713

Currently JavaScript is not multithreaded, but the things will change in near future. There is a new thing in HTML5 called Worker. It allows you to do some job in background.

But it's currently is not supported by all browsers.

Upvotes: 36

Dan Monego
Dan Monego

Reputation: 10087

JavaScript is absolutely not multithreaded - you have a guarantee that any handler you use will not be interrupted by another event. Any other events, like mouse clicks, XMLHttpRequest returns, and timers will queue up while your code is executing, and run one after another.

Upvotes: 14

Jeff Sternal
Jeff Sternal

Reputation: 48583

The JavaScript (ECMAScript) specification does not define any threading or synchronization mechanisms.

Moreover, the JavaScript engines in our browsers are deliberately single-threaded, in part because allowing more than one UI thread to operate concurrently would open an enormous can of worms. So your assumption and implementation are correct.

As a sidenote, another commenter alluded to the fact that any JavaScriptengine vendor could add threading and synchronization features, or a vendor could enable users to implement those features themselves, as described in this article: Multi-threaded JavaScript?

Upvotes: 18

gnarf
gnarf

Reputation: 106332

No, JavaScript is not multi-threaded. It is event driven and your assumption of the events firing sequentially (assuming they load sequentially) is what you will see. Your current implementation appears correct. I believe jQuery's .getScript() injects a new <script> tag, which should also force them to load in the correct order.

Upvotes: 88

Related Questions