×

Error message

The spam filter installed on this site is currently unavailable. Per site policy, we are unable to accept new submissions until that problem is resolved. Please try resubmitting the form in a couple of minutes.
mattia.minotti's picture

JavaScript, by its nature, isn’t neither multi-threaded nor pure single-threaded. The greatest majority of implementations supplied by Web browsers, however, has always been single-threaded. Only recently, with the introduction of the Web Workers API in HTML 5 standard, it has been created a multi-threading notion, based on the use of multiple .js file, even if nowadays it isn’t used in a structured way as it is in other programming languages (C, Java, ect…).
Considering the use linked to the Web UI development, the main limit of the JavaScript single-threaded nature has always been the fact that performing onerous procedures, from the computation point of view, implies the temporary freezing of the whole UI.
With the increasing complexity of Web Applications,changed now into RIA (Rich Internet Applications), such aspect has been steadily growing in importance, but it still remains a partially unsolved problem.

Atypical Single-Threading
Even if it doesn’t offer a real support to multi-threading, JavaScript supplies certain functions as the setTimeout or setInterval which behaviour may be seen as a computational parallelism. In reality, it only exploits priority mechanism in order to simulate the expected result.
Basically, both the functions allow to insert a portion of code into the execution queue (which is single, because the language is single-threaded) with a main priority which makes its execution probable, but not certain, at a particular time specified. That which in other languages ​​can be achieved through the execution of multiple threads, is obtainable in JavaScript using a kind of interleaving, ruled by priority mechanisms.
It’s clear that we are not speaking about a real multi-threading but these functions can’t be used for developing applications able to take advantage of the calculation parallelism in an advanced way. In certain cases, though, these functions allow to bypass the limits of language, obtaining the same results.

Extjs 4 and reactivity
Extjs, as every framework developed in JavaScript, endorses its strenghts and weaknesses and it’s subjected to the limits of the single-threaded model. The following is a practical example that can help you to understand these problems:

function get_random_color() {
    var letters = '0123456789ABCDEF'.split('');
    var color = '#';
    for (var i = 0; i < 6; i++ ) {
        color += letters[Math.round(Math.random() * 15)];
    }
    return color;
}

Ext.application({
    name: 'TestApp',
    
    launch: function() {
        
        var rightContainer = Ext.create('Ext.container.Container',{
            region:'center'
        });
        
        var menustore = Ext.create('Ext.data.TreeStore', {
            root: {
                expanded: true,
                children: [
                    { text: "choice1", leaf: true },
                    { text: "choice2", leaf: true },
                    { text: "choice3", leaf: true }
                ]
            }
        });

        var menu = Ext.create('Ext.tree.Panel', {
            title: 'Menu',
            region: 'west',
            width: 200,
            store: menustore,
            rootVisible: false,
            listeners: {
                'selectionchange': function(){
                        for(var i=0; i < 20000; i++){
                            console.log('x');
                        }
                        rightContainer.getEl().setStyle('background',get_random_color());
                }
            }
        });
        
        var viewport = Ext.create('Ext.container.Viewport', {
            layout: 'border',
            items: [
                menu,
                rightContainer
            ]
        });
    }
});

The code above is a simple snippet that, using the ExtJs 4 framework, renders a viewport divided into two panels. On the left, there’s a menu tree with three selectable items while you can find a colored container on the right. Clicking on one of the menu items you can simulate the execution of an heavy computational operation (in the example above it’s the printing of 20.000 messages in console log, but in a real case it could be the building of a complex interface) and then, the visualization of a new color on the right-hand container.

'selectionchange': function(){
 	for(var i=0; i < 20000; i++){
             console.log('x');
        }
        rightContainer.getEl().setStyle('background',get_random_color());
}

Executing the code, you will immediately notice an unexpected result: clicking on a menu item, it won’t change its state instantly. The item won’t change state until the heavy computational operation isn’t done. From the user point of view, it ends up in a feeling of non-reactivity of the interface that is certainly quite unpleasant.
The explanation to this behaviour lies in the fact that, being a single threaded execution, the framework applies the style into the component only when the function that works as handler returns. However, the function requires some time for its execution.
In a language that supports multi-threading, the solution would have been that of executing all the operations inside of the handler on a secondary thread and realising immediately the control of the principal thread which attends to the UI. How can we solve this problem in JavaScript?

The trick of the setTimeout
There’s a trick, that I feel to reccomend, useful to solve the problem of the user interface reactivity and it’s based on the use of the primitive setTimeout of JavaScript.
The solution consists in executing all the handler block with a timeout of 1ms, as it is shown below:

'selectionchange': function(){
 	setTimeout(function(){
               for(var i=0; i < 20000; i++){
                      console.log('x');
               }
               rightContainer.getEl().setStyle('background',get_random_color());
        }, 1);
}

Doing so, the execution of the handler is instant and the framework completes all its procedures, even the rendering of the item selected from the menu. The body of the function used as a parameter to the setTimeout is executed with main priority after a 1ms from the handler call (imperceptible to the user), but only after the execution of the various framework procedures.
Substantially, in this way, the priority of the code execution has been inverted, the menu interface update is prior to the event management. The result is definitely more relevant.

Obviously, this is just a simple trick and it doesn’t solve all the problems deriving from the lack of a true multi-threading in JavaScript.
Nevertheless it can be useful in order to understand how the execution cycle works in the modern browsers and how it is possible to develop applications that, in spite of their complexity, are able to guarantee a certain level of reactivity for the user interface.

Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.