0

私は(JavaScript/jQueryで)重い計算をします。問題は、これらの計算がUIスレッドをブロックしており、I(試してみた)がこれを回避する方法を見つけることができないということです。重いJavaScript計算ブロック

いくつかの要件:

  • 私はwebWorkers
  • を使用することはできません計算は、クライアント側でなければなりません(私は、サーバー側でそれを行うためのAJAX呼び出しを行うことはできません)

私はAndroidプログラマですので、Javaでこれを行う方法(スレッドの起動、計算、UIスレッドへのデータ送信)を知っていますので、ここでも同じことをしようとしています。

これらの重い計算はアクティブなインスタンスを1つしか持てません(私はGIFを作成してその前にこれを再起動することはできません)ので、複数の呼び出しを管理する必要はありません)。ここで

コードです:

var datas = []; // 10000 datas here 
function sortBy(param, paramType, order) { 
    var newArray = JSON.parse(JSON.stringify(datas)); 

    window.setTimeout(function(){ 
     var end = false; 
     for (var i = newArray.length - 1; i > 0 && !end; i--) { 
      end = true; 
      for (var j = 0; j < i - 1; j++) { 
       var sort = false; 

       if (paramType.localeCompare("str") == 0) { 
        if (newArray[j + 1][param].localeCompare(newArray[j][param]) < 0 && order.localeCompare("up") == 0) { 
         sort = true; 
        } else if (newArray[j + 1][param] > newArray[j][param] && order.localeCompare("down") == 0) { 
         sort = true; 
        } 
       } else if (paramType.localeCompare("nbr") == 0) { 
        if ((newArray[j + 1][param] - newArray[j][param]) < 0 && order.localeCompare("up") == 0) { 
         sort = true; 
        } else if ((newArray[j + 1][param] - newArray[j][param]) > 0 && order.localeCompare("down") == 0) { 
         sort = true; 
        } 
       } 

       if (sort) { 
        var tmp = newArray[j + 1]; 
        newArray[j + 1] = newArray[j]; 
        newArray[j] = tmp; 
        end = false; 
       } 
      } 
     } 

     datas = newArray; 
    }, 0); 
} 

私は件のデータをソートしています(と私は、サーバー側でこれを行うことができない理由携帯電話用のサーバーからの回避データのリロードのために、それはです)。

私は、データを含む初期変数が関数にないためUIスレッド上にあったと考えたので、関数内の配列をコピーしようとしました(完全コピー、参照なし)。関数にアクセスすると、UIスレッドが呼び出されます。 =>は動作しません。(だから私は間違っている)。

私はそれは私が=>があまりにも動作しない他のスタックオーバーフロー同様の質問に多くの時間を参照してください溶液であり、あなたが見ることができるようにsetTimout({computations}, 0)で計算を起動しようとしました。

私は基本的なJavaScriptエンバイロメントで動作しますが、私が使用するライブラリはjQueryだけです。

これは、この計算を他のスレッド(またはそのようなもの)、またはよりグローバルにするように強制する方法です。はUIスレッドをブロックしませんか?

+1

見てください[ここ](http://stackoverflow.com/a/10344560/27414)。ここでは、バックグラウンドの作業をチャンクに分割し、更新するUIの間に区切りを入れます。 –

+0

なぜWebワーカーを使用できないのですか? –

+0

@AkshatMahajan、すべてのデバイス/ブラウザとの互換性がないためです。 – Lucsartes

答えて

3

Javascriptはシングルスレッドです。 wbワーカーを使用しない限り、唯一の選択は計算を分割して分割することです。計算を実行し、次の部分の実行をスケジュールするにはsetImmediateまたはsetTimeoutを使用します。これはUIの実行時間を与え、あなたが見つけたブロックを防ぎます。