Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   setTimeout как он работает??? (https://javascript.ru/forum/misc/14716-settimeout-kak-rabotaet.html)

namo86 27.01.2011 18:50

setTimeout как он работает???
 
Есть у меня задачка одна, вывести большой объем данных на карте, очень большой, от 10 000 объектов, так вот сначала сделал все просто тупо в цикле, но потом понял, что это очень трудно для проца, во время выполнения цикла браузер благополучно зависал секунд на 10. Для борьбы с этой проблемой решил использовать функцию setTimeout с минимальной задержкой, все в общемто получилось, но чтото терзают меня смутные сомнения, всеже setTimeout асинхронная функция, поэтому возник вопрос, а не может ли одна и таже функция запуститься одновременно?

В это случае это может нарушить структуру данных, учитывая что счетчик текущей операции увеличивается внутри функции выполнения progressCurent++;

namo86 27.01.2011 19:23

не до конца описал условия, сама функция выглядит примерно так:

var progressCurent = 0, arrayList = [];
			
var func = function() 
{
	if( arrayList[progressCurent] )
	{
		// logic ... 
		
		progressCurent++;
		
		setTimeout(func, 10);
	}
}

setTimeout(func, 10);

Sweet 27.01.2011 19:55

Цитата:

Сообщение от namo86
не может ли одна и таже функция запуститься одновременно

Нет, такого в javascript быть не может

dmitriymar 27.01.2011 20:52

Цитата:

Сообщение от namo86
всеже setTimeout асинхронная функция, поэтому возник вопрос, а не может ли одна и таже функция запуститься одновременно?

но ты не можешь предсказать их последовательность запуска -если ещё извне будет запускаться не один раз -будет зависеть от производительности отдельно взятого компа

Sweet 27.01.2011 21:35

Цитата:

Сообщение от dmitriymar
но ты не можешь предсказать их последовательность запуска -если ещё из вне будет запускаться не один раз -будет зависеть от производительности отдельно взятого компа

Это ж надо было так не по-русски написать...

dmitriymar 27.01.2011 21:37

Цитата:

Сообщение от Sweet
Это ж надо было так не по-русски написать...

зато понятно

namo86 28.01.2011 16:03

Цитата:

но ты не можешь предсказать их последовательность запуска
В этом и вопрос, в принципе, установка нового события setTimeout происходит только в конце выполнения текущего события, так что пересечений быть не должно, но малоли чего :) поэтому и спросил :)

Мне кажется гораздо больше шансов у подобного бага при использовании функции setInterval нежели setTimeout ...

Kolyaj 28.01.2011 16:06

В вашем коде всё нормально, кроме того, что он будет выполнятся очень медленно. В IE, например, минимально возможная задержка для setTimeout -- 15 мс, в Fx -- 11 мс, в остальных браузерах получше дела обстоят.

namo86 28.01.2011 18:07

Цитата:

Сообщение от Kolyaj (Сообщение 90230)
В вашем коде всё нормально, кроме того, что он будет выполнятся очень медленно. В IE, например, минимально возможная задержка для setTimeout -- 15 мс, в Fx -- 11 мс, в остальных браузерах получше дела обстоят.

Chrome: затрачено времени 18894 мс.
Opera: затрачено времени 21887 мс.
Firefox: затрачено времени 30952 мс.
IE: затрачено времени 94647 мс.

Дауж ... и это только 1541 объект, ну как вариант можно увеличить количество операций в одном событии, в данный момент, одно событие одна операция, но все же это лучше чем полностью подвешивать браузер на 10-20 сек на i5, боюсь себе представить что твориться на машинках послабее.

x-yuri 28.01.2011 20:16

namo86, начать стоит с того, зачем столько объектов на карте? Может их можно не все сразу выводить? Расскажи поподробнее

namo86 31.01.2011 16:21

Цитата:

Сообщение от x-yuri (Сообщение 90263)
namo86, начать стоит с того, зачем столько объектов на карте? Может их можно не все сразу выводить? Расскажи поподробнее

Задача состоит в том, чтобы вывести данные из GPX файла, например такого: http://www.gpslib.ru/tracks/info/130..._14-35-57.html ... Точек: 50357 ... Основная часть данных это координаты трека (google.maps.Polyline), код получился примерно такой:

var point = new google.maps.LatLng
(
	_this.trackData.points[progressCurent].gps.lat,
	_this.trackData.points[progressCurent].gps.lng
);

if( !_this.hasOwnProperty('googleMapTrackPath') )
{
	_this.googleMapTrack = new google.maps.Polyline
	({
		strokeColor: '#2a72a8',
		strokeOpacity: 0.5,
		strokeWeight: 5,
		map: _this.googleMap
	});

	_this.googleMapTrackPath = _this.googleMapTrack.getPath();
}

_this.googleMapTrackPath.push(point)


Как уже писал, если не использовать setTimeout, при выводе браузер просто зависает, невозможно понять, работает он или висит и сколько он ещё будет грузиться. С помощью setTimeout проблема полностью решается, единственный нюанс это время загрузки, но и это думаю не такая уж большая проблема, самый оптимальный вариант как мне видится, увеличить количество обрабатываемых точек за один выполнение функции setTimeout, можно даже подумать насчет автобалансировщика нагрузки, с помощью пресловутой функции (new Date()).getTime(); и в случае быстрого выполнения одного цикла, добавлять максимальное количество обрабатываемых точек.

Кстати если есть материалы по этому поводу, былобы любопытно почитать.

person 01.02.2011 07:05

Цитата:

Сообщение от Kolyaj
В IE, например, минимально возможная задержка для setTimeout -- 15 мс, в Fx -- 11 мс

На моей машине 6 осёл видит разницу между 10мс и 11мс, а вот ниже 10 уже всё одинаково.
Это что, зависит от конкретной машины?

Kolyaj 01.02.2011 09:16

person,
что значит видит?

person 02.02.2011 06:42

Ты говоришь меньше 15 не понимает, а я говорю у меня понимает.
10 и 11 это разное время, а всё что меньше 10, уже одинаково и всегда равняется 10.

Kolyaj 02.02.2011 08:25

Цитата:

Сообщение от person
Ты говоришь меньше 15 не понимает

Понимать-то понимает. Но задержку делает в среднем 15мс, когда-то больше, когда-то меньше.

x-yuri 02.02.2011 08:41

person, еще раз, ответ на вопрос "что значит видит?" не прозвучал. Например, один из вариантов определения такой:
var i = 0, d = new Date(), N = 1000;
(function() {
    if (i < N) {
        i++;
        setTimeout(arguments.callee, 1);
    } else {
        alert((new Date() - d) / N);
    }
})();

а ты как определяешь?

x-yuri 02.02.2011 09:01

хотя результаты у меня примерно такие: opera - 1, chrome - 4, ff - 10, ie6 - 10 (а сначала -4 выдал :lol:)

по поводу анимации в фреймворках: jQuery и mootools используют setInterval для анимации, причем первый с шагом 13ms, а второй где-то 16ms (60 fps)


Часовой пояс GMT +3, время: 20:00.