2009-07-15 16 views
0

私はJavascriptルーチン(約400の複雑なもの)によって初期化されなければならない多くのウィジェットを使用する特定のページを持っています。これには時間がかかります(遅いマシンでは20秒もかかる)。今では、ページの代わりに進捗インジケータ(パーセントラベル付きの単純なテキストフィールド)を表示できると思っていましたが、私はそれを継続的に更新していても、進行中のタスクはすべてをブロックし、重いjavascriptタスクが完了するまで、すべてがフリーズしたままです。私は(...とFirefoxは、スクリプトが完了する時間がかかりすぎていることを述べている)も、次のような実験を行って、が、同様にフリーズ:Javascriptで長いタスクを監視する

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); 
} 

私に来る唯一の解決策は、長い仕事を打破することです断片を入れてラベルを更新する....しかし、別の解決策があるかどうか疑問に思っていた!神、JSスレッドをできるだけ早く必要があります... :)

アイデア?

答えて

1

スクリプトがonLoadイベントから実行されていると仮定して、ユーザーが実行中に空白のページに座っていないとすることはできますか?

もしそうなら、これらの関数の配列を作成し、その配列を反復して関数を評価し、N個の関数ごとに進捗インジケータを更新することでスクリプトを別々の関数に分割することをお勧めします。

公開されているウェブサイトの場合は、そのページを実際に体験するために必要なJavaScriptの量を最小限に抑えてください。そして各ウィジェットが必要とする初期化の量。エージェントスミスを言い換えてみましょう:誰もそれらを見るのを待っていないなら、アコーディオンフォールドツリーは何ですか?

+0

+1を「ピップ」とdiv要素を持っているBを呼び出すために持っていると仮定です!他のすべてが失敗したときに私はそれについて考える。 – ATorras

+0

あなたの解決策は残念ながらうまくいかない。その理由は、長い仕事関数が返されるまで、他の関数を呼び出すとしても、何も更新されません(少なくともFFで)。唯一の方法は、グローバル変数を保持し、次のようにすることです: - 1から20までのことを行い、関数を使ってsetTimeout(1msのようにプリエンプションを持つ)を更新してから、 を返します。コールバック時に、 21〜40、setTimeoutなど... これは、この作業を正しく行うための唯一の方法だと思います。つまり、タイムシェアリングをエミュレートすることです。 – gotch4

+0

...まさに私が書いた解決策です。 – kdgregory

0

スレッドが必要な場合は、LiveConnectを使用して、真のJavaスレッドを作成できます(セキュリティマネージャで許可されている場合)。

Cのコルーチンのデザインパターンを使用できない場合は、

よろしくお願いいたします。

0

これは動作しますが、あなたがそれを起動するとid =もちろん

<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> 
関連する問題