Please wait modal overlay before waiting for a function with a heavy workload without setTimeout()?
-
22-09-2019 - |
Question
This is a simplified example, to make sure that there are no asynchronous fading/animation functions involved.
I want, that the background is red when the function with the heavy workload works and turns to black, when it is ready. What actually happens is, that most times the background will turn directly to black, after the function is ready. Yo will not see a red background, even if you are waiting for 'done' be alerted.
Is there a better solution, then wating a few milliseconds with setTimeout, so that the background change to red happens. To call work() directly produces the problem.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Test</title>
<script type='text/javascript'>
function work()
{
var i, a;
a = [];
for(i = 0; i < 250000; i++)
{
a.push(Math.random());
}
a.sort();
document.getElementsByTagName('body')[0].style.background = '#000000';
alert('done');
return true;
}
window.onload = function() {
document.getElementsByTagName('body')[0].style.background = '#ff0000';
//work();
setTimeout(work, 100);
};
</script>
</head>
<body>
<h1>Test</h1>
</body>
</html>
Solution
The "modal popup" is there to save the script from completely (forever) locking up the browser and making the user really upset. This guard is not detectable from JS code and pauses the JS execution which follows a synchronous model. It is to save you, write code that doesn't block! It's actually fairly easy to setup most computations to be resumable and cancleable through use of thunks/closures or queues.
Anyway ... in my experience, a "delay" of 1ms is enough in FF3.5 (Win) and IE6-8 to update the CSS (the actual delay will most likely be more than 1ms). This forces the "queuing" of the event post back inside the synchronous model which, at least in the cases above, allows the CSS styles to be applied before execution of JS continues. I think Prototype.js uses a value of 0ms for it's "delay" function, but I am not that brave.
Also, 'document.body' :-)
(I am quite sure there is no "better" way, although this entire approach smells like an open-air fish market.)