5

jQuery/JavaScriptを多用する Web アプリケーションがあります。メモリ内に大きな配列を保持し、ユーザーはテキスト ボックスに入力してフィルター処理します。

問題: フィルタリング アルゴリズムが実行されると、アプリケーションが応答しなくなり、ブラウザがスクリプトを続行するかどうかをユーザーに尋ねることさえあります。

最適には、応答しないことを避けるために、フィルター関数を別のスレッドで実行したいと思います。これは何らかの方法で可能ですか?または、回転する砂時計などを表示したいのですが、負荷の高いスクリプトを実行すると、ブラウザがアニメーション GIF を表示できないようです。

問題を攻撃する最善の方法は何ですか?

4

3 に答える 3

3

ブラウザは、メインのイベント処理スレッドでスクリプトを実行します。これは、実行時間の長いスクリプトがブラウザのキューを保持する可能性があることを意味します。

フィルタロジックをチャンクに分割し、タイムアウトコールバックで実行する必要があります。実行の間に0ミルのギャップを使用できます。0ミリはブラウザへの単なる提案ですが、ブラウザは後続のコールバック間のギャップを使用してイベントキューをクリアします。タイムアウトは通常、ページが「ハング」するのを防ぐために、ブラウザ環境で実行中のスクリプトを実行する必要がある時間です。

于 2012-09-14T07:06:18.833 に答える
2

このタイプのジョブは、Webワーカーが設計されたものであり、サポートにはパッチがありますが、改善されています。

于 2012-09-14T07:02:01.247 に答える
2

forおそらくループを使用している配列を処理していることを考えると、以前の私のコメントを拡張します。for単純なループを簡単にリファクタリングしsetTimeout()て、作業をチャンクに分割し、ブラウザが各チャンク間でスクリーン ペイントとユーザー インタラクションを処理できるようにすることができます。簡単な例:

// Generic function to execute a callback a given number
// of times with a given delay between each execution
function timeoutLoop(fn, startIndex, endIndex, delay) {
    function doIteration() {
        if (startIndex < endIndex){
            fn(startIndex++);
            setTimeout(doIteration, delay);
        }
    }
    doIteration();
}

// pass your function as callback
timeoutLoop(function(i) {
   // current iteration processing here, use i if needed;
}, 0, 100, 0);

デモ: http://jsfiddle.net/nnnnnn/LeZxM/1/

これは、一般的なアイデアを示すためにまとめたものですが、明らかにさまざまな方法で拡張できchunkSizeますtimeoutLoop()。への呼び出しfn())など

于 2012-09-14T07:50:34.350 に答える