Reputation: 1591
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
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
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