私は本当に巨大な配列を持っています。それには何百万ものオブジェクトが含まれている可能性があり、次のようになります
srcArray = [{
'name': 'AAA',
'keyA': true,
'keyB': 'blahblah'
},
//...
{
'name': 'ZZZ',
'keyA': false,
'keyB': 'testString'
}];
一致するすべてのオブジェクトを見つけて、別の配列に入れる必要があります。問題は、この単一の配列が大きすぎて処理できないため、メモリに入れることができないことです。アイデアは、それを小さな部分に分割し、最初の部分を取得し、何かを実行してから、次の部分に置き換えます...というように、最後の部分まで. この例を参照してください (3 つの非常に小さい部分):
パート 1、ファイルpart1.js :
srcArray = [{
'name': 'A1',
'boolA': false,
'strB': 'testString'
}, {
'name': 'B1',
'boolA': false,
'strB': 'blahblah'
}, {
'name': 'C1',
'boolA': true,
'strB': 'blahblah'
}];
パート 2、ファイルpart2.js :
srcArray = [{
'name': 'A2',
'boolA': false,
'strB': 'blahblah'
}, {
'name': 'B2',
'boolA': true,
'strB': 'testString'
}, {
'name': 'C2',
'boolA': false,
'strB': 'blahblah'
}];
パート 3、ファイルpart3.js :
srcArray = [{
'name': 'A3',
'boolA': true,
'strB': 'blahblah'
}, {
'name': 'B3',
'boolA': false,
'strB': 'blahblah'
}, {
'name': 'C3',
'boolA': false,
'strB': 'testString'
}];
コード:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test</title>
<script src="jquery.min.js"></script>
<script type="text/javascript">
srcArray = [];
found = [];
</script>
<script>
$(document).ready(function () {
var loadScripts = function (scripts) {
var result = function () {
delete srcArray;
srcArray = undefined;
console.log(found);
}
var func = function (i) {
if (i >= scripts.length) return result();
var head = document.getElementsByTagName("head")[0];
var scr = document.createElement('script');
scr.src = scripts[i];
var f = false;
scr.onload = scr.onreadystatechange = function () {
if (!f && (!scr.readyState || scr.readyState == "loaded" || scr.readyState == "complete")) {
f = true;
search('testString', srcArray);
setTimeout(function () {
func(++i)
}, 50);
scr.onload = scr.onreadystatechange = null;
if (head && scr.parentNode) {
head.removeChild(scr);
}
}
}
return head.insertBefore(scr, head.firstChild);
}
func(0);
}
function search(s, arr) {
for (var i = arr.length; i--;) {
for (key in arr[i]) {
if (typeof (arr[i][key]) === 'string' && arr[i].hasOwnProperty(key) && arr[i][key].indexOf(s) > -1) found.push(arr[i]);
}
}
return found;
};
$('.click').click(function () {
delete found;
found = undefined;
srcArray = [];
setTimeout(function () {
found = [];
loadScripts(["part1.js", "part2.js", "part3.js"])
}, 50);
});
});
</script>
</head>
<body>
<span class="click">click me</span>
</body>
</html>
はい、グローバル変数が醜いことはわかっていますが、別の方法がわかりません。このコードを 10 個の部分でテストしました (各配列には 25 万個のオブジェクトが含まれていました。つまり、10 個の部分には 250 万個のオブジェクトが含まれていました。合計データ サイズは約 260MB です)。このテストを完了するのに約 20 秒かかりましたが、時間は気にしません。メモリは気にします。Firefox は、4 回のクリックで 140 MB の RAM を占有するのが最も優れていました (つまり、ブラウザは 1 GB を超えるスクリプト内で検索したことを意味します)。データ! 非常に良い結果!)、Chrome と Opera 11.52 ははるかに悪く、IE9 は最初のクリックの後に約 1GB の RAM で 2 回目のクリックで失敗しました。
質問 1. このような問題を Javascript で解決することはできますか? 巨大なデータを検索してメモリ リークを回避することは可能ですか?
質問 2. プロセスを停止するには? つまり、ある#stop
要素をクリックすると、関数はその配列を停止して解放する必要がありfound
ます (関数が既に見つけたのと同じ数のオブジェクトが含まれます)。