@alsmile

Как оптимизировать цикл — перебора «for» JavaScript?

Прошу помочь придумать адекватное решение для выполнения скрипта, очень буду рад подсказкам по оптимизации... Сейчас, после 2 минут выполнения жрет свыше 2 ГБ RAM и в конечном итоге повесит браузер. Использую его локально. Словарь для перебора около 3 миллионов элементов, каждый массив - это файл, содержит по 15 элементов, подгружаю циклом for. Пытаюсь придумать поэтапное выполнение скрипта, например, по выполнении скрипта с каждым 5 массивом сделать break, и потом начать выполнение цикла for уже не с 1 файла, а с 6. Каким образом реализовать такой callback?

$(document).ready(function() {
    //Подключение словаря
    function textFileToArray(filename) {
        var reader = (window.XMLHttpRequest != null) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        reader.open("GET", filename, false);
        reader.send();
        return reader.responseText.split(/\n/g);
    }
    //Запускаем цикл
    for (var ir = 1; ir < 1000; ir++) {
        var arr2 = textFileToArray("RUS-1-3/RUS-1-3.part" + ir + ".lst");
        if (arr2) {
            setTimeout(function() {
                arr2.forEach(function(item2, i, arr2) {
                    JsHttpRequest.query(
                        'ajax.php', {
                            'Action': 'GetLocationList',
                            'city': item2
                        },
                        function(result, errors) {
                            // Пишем ошибки
                            document.getElementById("debug").innerHTML = errors;
                            if (result) {
                                //console.log(result);
                                // Пишем результат, если он положительный
                                if (result.Content.geonames) {
                                    var arr = result.Content.geonames;
                                    arr.forEach(function(item, i, arr) {
                                        var list = document.getElementById('ans');
                                        list.innerHTML = list.innerHTML + '<tr><td> ' + item.cityName + '</td>' + '<td>' + item.countryId + '</td>' + '<td>' + item.countryName + '</td>' + '<td>' + item.id + '</td>' + '<td>' + item.name + '</td>' + '<td>' + item.regionId + '</td>' + '<td>' + item.regionName + '</td></tr>';
                                    });
                                }
                            }
                        }
                    );
                }, 5000);

            });
        }
    }
});
  • Вопрос задан
  • 855 просмотров
Решения вопроса 1
Stalker_RED
@Stalker_RED
Сейчас ваш скрипт запускает textFileToArray() с максимально возможной скоростью, и запускает множество setTimeout(..., 5000) которые запустятся через 5 секунд, много-много штук почти одновременно. Я догадываюсь, что вы хотели чего-то другого, но по вашему описанию непонятно чего именно.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
dasha_programmist
@dasha_programmist
ex Software Engineer at Reddit TS/React/GraphQL/Go
использовать WebWorker
www.w3.org/TR/workers

или разбить на пакеты и учиться использовать промисы:
var requestAsync = function (cb, ecb) {
    var pr = $.Deferred();
    $.ajax({
        url: url,
        type: 'post',
        data: {
        },
        success: function (data) {
            if (cb)
                cb(data);
            pr.resolve();
        },
        error: function (xhr, status, error) {
            if (ecb)
                ecb();
            pr.resolve();
        }
    });
    return pr;
};
var chunkSize = 5;
var f = function(fcb){
	var promises = [];	
	for (var i = 0; i < Math.min(urls.length, chunkSize); i++)
		promises.push(requestAsync(args));
	if(promises.length)
		$.when.apply($, promises).done(function(){
			setTimeout(f.bind(fcb, this), 1);
		});
	else{
		fcb();
	}
}
f(function(){
	console.log('complete');
});

но стоит помнить о проблемах: jquery промисы не являются промисами а+
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы