views:

70

answers:

3

Hello, I have a particular page that uses lots of widgets that have to be initialized by Javascript routines (around 400, it's a complex one). This takes some time (even 20 secs on slower machines). Now I was thinking I could show a progress indicator (a simple text field with a percentage label), instead of the page, but I discovered that even if I was updating it continuosly, the ongoing task blocks everything and I see no updates. So everything remains frozen until the heavy javascript task completes. I even done the following experiment, but freezes as well (and firefox says that the script is taking too long to complete...):

function a(){
 for (var i = 0; i < 5000000000000000; i++){
  abb = i;  
 }
}

var abb;

function c(){
 var ef = document.getElementById("pip");
 ef.innerHTML = abb;

}

function b(){

 setInterval(c, 50);
 setTimeout(a, 1000);
}

The only solution that comes to me is to break down the long job in pieces and update the label.... but I was wondering if there is another solution! God, JS needs threads as soon as possible... :)

Any ideas?

+1  A: 

Can I assume that the scripts are being executed from an onLoad event, so that the user isn't sitting at a blank page while it runs?

If yes, then I'd recommend breaking the scripts into separate functions, creating an array of those functions, iterating through that array and evaling the functions, and updating your progress indicator after every N functions.

And if it's a public-facing website, try to minimize the amount of JavaScript that's absolutely necessary to experience the page. And the amount of initialization that each widget needs. To paraphrase Agent Smith: what good are accordian-fold trees, if nobody waits to see them?

kdgregory
+1 Of course! I think about it when everything else fails
ATorras
your solution unfortunately won't work. The reason is that until the long job function returns, even if it calls others, nothing will be updated (at least on FF). The only way is to keep a global var, and go on like this: - do things from 1 to 20,update counter, setTimeout (like 1ms, just to have prehemption) with function then return - upon callback, do things from 21 to 40, setTimeout and so on...I think this is the only way to get this work properly, that is to emulate time sharing.
gotch4
... which is exactly the solution that I described
kdgregory
then sorry because I misunderstood you :D Anyway I'm trying the coruotine stuff mixed with this... may be a nice tool if properly devoloped.. I'll let you know!
gotch4
A: 

Hi,

If you want threads you can use LiveConnect and create true Java Threads (if security manager allows it).

If don't you can use C's coroutines design pattern.

Regards.

ATorras
A: 

This works, it's assumed you've got to call b to start it up and have a div with id = "pip"

<html>
<head>
    <script type="text/javascript">

    var i;
    var state = 0;

    function a(){

     switch(state){

     case 0:
      i = 0;
     case 1:
      i++;
      for (; i < 5000000000000000; i++){
       abb = i;
       if (i%1000 == 0){
        setTimeout(a, 1);
        state = 1;    
        return;    
       }     
      }
     break;
     }
    }

    var abb;

    function c(){
     var ef = document.getElementById("pip");
     ef.innerHTML = abb;

    }

    function b(){

     setInterval(c, 50);
     setTimeout(a, 1000);
    }

    </script>
</head>
<body onload="javascript:b();">
    <div id = "pip">test</div>
</body>
</html>
gotch4