2016-08-02 11 views
0

私のアプリケーションでは、非常に大きな配列(arround 60kレコード)があります。 forループを使用して、以下に示すようにいくつかの操作を行っています。私はこのループを実行すると、Firefoxで&が、ショーはこのページのスクリプトがビジー状態である可能性があり」と言って、ポップアップ、またはそれが応答を停止している可能性がある非常に大きいようjavascriptで大きな配列を扱う方法

var allPoints = []; 
for (var i = 0, cLength = this._clusterData.length; i < cLength; i+=1) { 
    if (allPoints.indexOf(this._clusterData[i].attributes.PropertyAddress) == -1) { 
     allPoints.push(this._clusterData[i].attributes.PropertyAddress); 
     this._DistClusterData.push(this._clusterData[i]) 
    } 
} 

ブラウザがハングアップします。これで、スクリプトを停止することができますスクリプトが完了するかどうかを確認することができます。ブラウザがハングしないようにするにはどうすればよいですか?

+0

このループを実行した後の目標は何ですか? –

+0

ページ番号などを追加してデータ量を減らすことはできますか?すべてのデータを処理しようとしているためブラウザがハングし、すべての操作が終了するまで待機します。私は、これをより速くするためにページネーションを追加するか、データの正規化を行うことをお勧めします。 –

+0

それは間違ったアプローチです、あなたのブラウザは間違いなくクラッシュします。 2つまたは3つの異なるタスクでタスクを分割しようとすることができます。あなたの問題を解決するかもしれない –

答えて

2

レスポンスを維持するには、コントロールをブラウザに戻す必要があります。つまり、現在の処理を終了し、後で再開するようにスケジュールするには、setTimeoutを使用する必要があります。例:

function processData(i) { 
    var data = clusterData[i]; 
    ... 

    if (i < clusterData.length) { 
     setTimeout(processData, 0, i + 1); 
    } 
} 

processData(0); 

これは現在の場所から行うのが最も簡単な方法です。

どちらかといえば、Web Workersは実際には別のスレッドに作業を分けているので、素晴らしい解決策になります。


これはあなたが現在行っていることは、非常に効率が悪いことです。値を配列にプッシュし、その結果、それより長い配列を繰り返しチェックし続けます。

var allPoints = {}; 

// for (...) ... 
if (!allPoints[address]) { // you can even omit this entirely 
    allPoints[address] = true; 
} 

// later: 
allPoints = allPoints.keys(); 
-1

は、一度に1000のレコードセットに対して、リストとは非同期のアレイに追加することを検討してみるか、最高のパフォーマンスを提供して何のために:あなたは代わりに、重複排除のためにオブジェクトキーを使用しなければなりません。これにより、一連の項目がリストに追加されている間にアプリケーションが解放されます。ここで

は、いくつかの追加情報は以下のとおりです。すべてのasync and await while adding elements to List<T>

0

まず、複数のthis._clusterData[i]呼び出しを避けます。

var allPoints = []; 
var current; 
for (var i = 0, cLength = this._clusterData.length; i < cLength; i+=1) { 
    current = this._clusterData[i]; 
    if (allPoints.indexOf(current.attributes.PropertyAddress) == -1) { 
     allPoints.push(current.attributes.PropertyAddress); 
     this._DistClusterData.push(current) 
    } 
} 

これは他の人がすでに指摘したように、あなたが非同期的にこれを行うことができますかなり

0

:-)あなたのパフォーマンスを向上させる必要がありますので、ブラウザが応答のまま:そのようにそれを変数に抽出します。

ただし、indexOfの操作は非常にコストがかかることに注意してください。 PropertyAddress値によってキーが付けられたMapを作成する方が良いでしょう。それは重複を処理します。

(function (clusterData, batchSize, done) { 
    var myMap = new Map(); 
    var i = 0; 
    (function nextBatch() { 
     for (data of clusterData.slice(i, i+batchSize)) { 
      myMap.set(data.attributes.PropertyAddress, data); 
     }  
     i += batchSize; 
     if (i < clusterData.length) { 
      setTimeout(nextBatch, 0); 
     } else { 
      done(myMap); 
     } 
    })(); 
})(this._clusterData, 1000, function (result) { 
    // All done 
    this._DistClusterData = result; 
    // continue here with other stuff you want to do with it. 
}.bind(this)); 
関連する問題