Lucsartes
Lucsartes

Reputation: 321

Heavy JavaScript computations block

I do (in JavaScript/jQuery) heavy computations. The problem is that these computations are blocking the UI thread and I (tried and) can't find a way to avoid this.

Some requirements:

I'm an Android programmer to so I know how to do that in Java (launching thread, make computations, send data to UI Thread) and so I'm trying to do the same thing here.

So these heavy computations can have only one active instance (I will make a GIF for advise the user he can't launch this again before that end) so don't need to manage multiple call (end last, start new).

Here is the code:

var datas = []; // 10000 datas here
function sortBy(param, paramType, order) {
    var newArray = JSON.parse(JSON.stringify(datas));

    window.setTimeout(function(){
        var end = false;
        for (var i = newArray.length - 1; i > 0 && !end; i--) {
            end = true;
            for (var j = 0; j < i - 1; j++) {
                var sort = false;

                if (paramType.localeCompare("str") == 0) {
                    if (newArray[j + 1][param].localeCompare(newArray[j][param]) < 0 && order.localeCompare("up") == 0) {
                        sort = true;
                    } else if (newArray[j + 1][param] > newArray[j][param] && order.localeCompare("down") == 0) {
                        sort = true;
                    }
                } else if (paramType.localeCompare("nbr") == 0) {
                    if ((newArray[j + 1][param] - newArray[j][param]) < 0 && order.localeCompare("up") == 0) {
                        sort = true;
                    } else if ((newArray[j + 1][param] - newArray[j][param]) > 0 && order.localeCompare("down") == 0) {
                        sort = true;
                    }
                }

                if (sort) {
                    var tmp = newArray[j + 1];
                    newArray[j + 1] = newArray[j];
                    newArray[j] = tmp;
                    end = false;
                }
            }
        }

        datas = newArray;
    }, 0);
}

I'm sorting datas (and for avoid data reload from server for mobiles, it's why I can't make this on server side).

I tried to copy (full copy, no reference) the array in the function, because I thought that the initial variable who contains the data, because she don't are in a function, was on the UI thread, and accessing it into the function makes call to UI thread. => doesn't work. (and so I'm wrong).

I tried to launch the computations in a setTimout( {computations}, 0) as you can see, that was a solution that I see a lot of time on other Stack Overflow similar questions => doesn't work too.

I run in a basic JavaScript environnement, the only library I use is jQuery.

So, is here a way to force this computations to work in an other thread (or something like that), or more global, don't block UI thread?

Upvotes: 1

Views: 1074

Answers (1)

Chris Tavares
Chris Tavares

Reputation: 30411

Javascript is single threaded. Unless you use a wb worker, your only choice is to split the computation up into pieces. Execute a piece of the calculation, then use setImmediate or setTimeout to schedule the next piece to run. This will give the UI time to execute and prevent the blocking you found.

Upvotes: 4

Related Questions