ricardo
ricardo

Reputation: 1591

Content change run after javascript

I am using a simple function that before it run a slow function, it put a text in the page with : "loading". But this text only show after the function finish. I did try to add a css too, but it only run after the function finish.

I put a exemple on fiddle and replace my big function with a sleep function. and the result is the same.

http://jsfiddle.net/9nzg9f6L/5/

here the code I am using in the html page:

<div  id='msg'>BEGIN</div>    
<div style="cursor: pointer; color:red;" id='clickme'>click me!</div>

here is the javascript code:

$("#clickme").click(function(){
    // this code only run after the sleep ...
    $('#msg').text("PROCESSING");

    console.log("text changed");

    sleep(5000);
    console.log("END function");

});


function sleep(miliseconds) {
    var currentTime = new Date().getTime();
    while (currentTime + miliseconds >= new Date().getTime()) {}
}

I cannot modify the sleep(5000) function. It is a placeholder for proprietary and obfuscated function.

even this: http://jsfiddle.net/9nzg9f6L/7/

does not work.

Upvotes: 1

Views: 63

Answers (2)

Dayan
Dayan

Reputation: 8031

Take a look at my updated jsFiddle which solves your problem.

http://jsfiddle.net/9nzg9f6L/10/

Updated Code

$("#clickme").click(function(){

    //Call slow func using a Self Executing func.
    (function(){
        //Create the deferred object to use
        var defObj1 = $.Deferred();

        //Call you slow func
        $('#msg').text("PROCESSING");
        setTimeout(function(){
                sleep(5000)
                defObj1.resolve();
        }, 500);

        return defObj1;  

    })().done(FunctionTwo);
})

//We call this once the Sleep function is done.
var FunctionTwo = function(){
    $('#msg').text("FUNCTION ONE COMPLETED OK..");
};

//Make it slow....
function sleep(miliseconds) {
    var currentTime = new Date().getTime();
    while (currentTime + miliseconds >= new Date().getTime()) {}
}

Here we make use of a Self-Executing anonymous function and jQuery's Deferred Object with a setTimeout to ensure the slow function executes without halting the entire app. Once done, we can call Function two which in this case simply outputs that the slow function completed.

Upvotes: 4

dfsq
dfsq

Reputation: 193291

The problem here is since javascript is single threaded language, browser just didn't have enough time to alter DOM before "slow" function blocks UI completely. To overcome this situation usually you delay slow operation by some very little time, so that DOM update can finish before bad code starts working:

$("#clickme").click(function(){

    $('#msg').text("PROCESSING");
    $('#msg').addClass("message");

    setTimeout(function() {
        sleep(5000);
    }, 50);
});

Demo: http://jsfiddle.net/9nzg9f6L/6/

But of course if it is possible to make slow code asynchronous it would be the best approach in this case. Blocking UI is never a good UX. Also look into WebWorkers.

Upvotes: 2

Related Questions