Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: для новичков > Остановить все потоки setTimeout


Автор: ProgramerForever 8.1.2012, 19:58
Добрый день, уважаемые участники форума.

Задача такая:
Есть стандартный вызов функции через setTimeout:
Код

   setTimeout('time()',1000);

Необходимо остановить все потоки, вызванные этой функцией.
Вообще для этого есть функция clearTimeout(id), где id - идентификатор потока, который получается так:
Код

id=setTimeout('time()',1000);

Но доступа к странице у меня, естественно, нет, поэтому и id мне недоступен напрямую.

Вопрос:
Как остановить потоки, или как добраться до id потоков?

Автор: Amphiluke 8.1.2012, 21:35
Если идентификатор таймера не сохранялся в глобальную переменную, то получить его из кода глобального уровня не получится никак… кроме тупого перебора. smile 
То есть, ИМХО, остается только воспользоваться тем фактом, что метод setTimeout всегда возвращает значение типа Number, которое в «обычных» условиях вряд ли будет больше, скажем, пары тысяч. smile  Ну может, пары десятков тысяч, в зависимости от того, насколько активно страница использует таймеры и сколько раз она обновлялась…

Автор: ProgramerForever 9.1.2012, 11:30
Обнадёживает, ага. Всё равно спасибо, попробую брутфорсом.

Автор: Amphiluke 9.1.2012, 11:36
Возможно, более подходящим способом будет (временно) переписать callback функцию, которая вызывается таймером?
Код

var orig_time = time;
time = function() {};
/* time = orig_time; // восстановить, когда все таймеры истекут или просто когда потребуется */

Автор: ksnk 9.1.2012, 12:49
ProgramerForever, 
А о чем вообще вопрос? Некто, в недоступном участке страницы с маниакальным упорством понапихал вызовов setTimeout(time,1000);
К рассматриваемому моменту, к примеру, setTmeout вызвался 10 раз и прямо сейчас вызывается time первый раз.
Автор функции time не желает, чтобы функция вызывалась оставшиеся 9 раз из этого цикла?

Почему бы не завести глобальную переменную, в которой проставить время последнего вызова и проверять это время при вызове функции?

Код

function time(){
   var date=new Date();
   if(time.lastDate && time.lastDate>date) return ;

   date.setTime(date.getTime()+1000);
   time.lastDate=date;

   ...

}


Правильно, конечно, будет открутить руки маньяку и написать свою собственную функцию установки таймаута, которая сохраняет в нужном месте идентификатор от setTimeout.

Автор: ProgramerForever 9.1.2012, 13:37
Amphiluke, сработал вот такой код:
Код

for (var i=0;i<100;i++) {clearTimeout(i);}

Всем спасибо.

Автор: Amphiluke 9.1.2012, 14:02
ProgramerForever, советую вам пообновлять страничку раз семь-десять. Во многих браузерах id-шники таймеров после обновления страницы не начинают нумерацию с начала, как при первом открытии страницы, а продолжают нумерацию, начатую еще при первом открытии страницы. Так что id-шники запросто могут «ускакать» далеко за сотню.

Вот пример для тестирования:
Код

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Noname</title>
<script type="text/javascript">
console.log("id=" + setTimeout(function() { console.log("a"); }, 1000));
console.log("id=" + setTimeout(function() { console.log("s"); }, 2000));
console.log("id=" + setTimeout(function() { console.log("d"); }, 3000));
console.log("id=" + setTimeout(function() { console.log("f"); }, 4000));
</script>
</head>
<body>

</body>
</html>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)