2016-08-02 46 views
0

在我的應用程序工作,我有一個非常大的陣列(以防萬一60K記錄)。使用for循環,我正在做一些操作,如下所示。如何與大陣在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]) 
    } 
} 

當我運行這個循環瀏覽器掛起,因爲它是非常大的&在Firefox是顯示彈出說「此頁上的腳本可能忙,或者它可能已停止響應。現在你可以停止腳本,或者你可以繼續看腳本是否會完成「。我該怎麼做才能讓瀏覽器不掛?

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