2012-01-14 2 views
4

Есть ли способ проверить clearTimeout был успешным.был clearTimeout успешный?

У меня есть функция javascript, которая выполняется с интервалом в 30 секунд асинхронно. Это функция самосогласования и использует setTimeout() для повторения в цикле. В конкретном случае мне нужно вызвать эту функцию после возникновения какого-либо события. Поэтому я сначала clearTimeout и снова вызываю функцию. Но я не знаю, смог ли я успешно очистить предыдущий цикл или я начал два отдельных цикла. Могу ли я сделать что-то вроде этого? :

if(clearTimeout(timer)) 
alert("cleared"); 
+1

Если вы передали правильный параметр, вы очистили цикл. Но если вы хотите чувствовать себя более безопасным, подумайте о передаче другого аргумента функции, которая является «истиной» или «ложной»; если 'false', функция не должна настраивать цикл. – Jon

+0

Я чувствую, что должен быть хороший способ отслеживать состояние вашего таймера и всегда быть уверенным, что ваш clearTimeout был успешным. Вот простая скрипка, чтобы люди начали. http://jsfiddle.net/ASYgU/ – mrtsherman

+0

@mrtsherman umm, я попытался немного поиграть с кодом; выдает значение таймера переменной. Оказывается, это число, которое увеличивается. Одно можно сказать наверняка: оператор 'if (timer)' всегда возвращает true и не может использоваться для проверки того, работает ли таймер. Но его можно использовать для отслеживания того, сколько раз цикл выполнялся. [updated fiddle] (http://jsfiddle.net/roopunk/ASYgU/4/) – roopunk

ответ

4

"Есть ли способ, чтобы проверить из clearTimeout был успешным."

Нет, в вашем распоряжении нет состояния, которое вы можете проверить, но если вы правильно управляете своими таймерами, это не должно быть проблемой.


Вы можете создать свой собственный объект с сохранением состояния таймера я полагаю ...

var _slice = Array.prototype.slice; 

    // substitute for setTimeout 
function myTimer(fn,ms) { 
    var args = _slice.call(arguments,2), 
     timer_state = { 
      complete: false, 
      timer: setTimeout(function() { 
       timer_state.complete = true; 
       fn.apply(this, args); 
      }, ms) 
     }; 
    return timer_state; 
}; 

    // substitute for clearTimeout 
function clearMyTimer(timer_obj) { 
    timer_obj.complete = true; 
    clearTimeout(timer_obj.timer); 
}; 

Пример очистки таймера ...

// create a timer 
var timer = myTimer(function() { 
    console.log('timer is done'); 
}, 1000); 

console.log(timer.complete); // complete? false 

clearMyTimer(timer); // clear it 

console.log(timer.complete); // complete? true 

Пример позволить ему бежать ...

// create a timer 
var timer = myTimer(function() { 
    console.log('timer is done'); 
}, 1000); 

console.log(timer.complete); // complete? false 

    // check the timer object after it has expired 
setTimeout(function() { 
    console.log(timer.complete); // complete? true 
}, 1500); 

EDIT: Обновлено, чтобы сделать this последовательным в строгом режиме и поддерживать дополнительный аргумент, переданный обратному вызову. Спасибо за комментарий @Saxoier.

+0

'myTimer' сломается, если вы запустите код в строгой среде (' 'use strict'') и используйте' this' в функция. Кроме того, переданные аргументы после задержки-arg будут проигнорированы.Дополнительные аргументы могут быть стандартизированы в HTML 5 - уже реализованы в Firefox, Chrome и Opera, но могут быть легко реализованы в средах, которые его не поддерживают. [jsFiddle] (http://jsfiddle.net/w3p8T/) – Saxoier

+0

@ Saxoier: Хорошие очки. Я обновил. Применял дополнительные аргументы непосредственно к обратному вызову вместо 'setTimeout', поэтому аргументы будут работать в типично неподдерживаемых браузерах. –

1

Да, это состояние, использующее закрытие. Это довольно прямолинейно.

Чтобы убедиться, что вы не называть его снова и снова, как вы говорите, вы можете попробовать что-то вроде этого ...

// declare only once, singleton concept using closure 
(function() { 
    var timerReference, 
    timerMethod = function(fn) { 
     fn(); 
     if (timerReference) { 
      window.clearTimeout(timerReference); 
     } 
     timerReference = window.setTimeout(function() { 
      timerMethod(fn); 
     }, 30000); 
    }; 
    window.doTimer = function(fn) { 
     timerMethod(fn); 
    }; 
})(); 

// you can call this as many times as you like 
doTimer(function() { 
    alert('hi'); 
}); 
doTimer(function() { 
    alert('hi again'); 
}); 

В этом случае вызывающему doTimer() уничтожит предыдущий перед ним так вы всегда будете иметь только один таймер.

Я также могу написать код, который будет стоять в очереди и ждать завершения последнего, но это еще одна запись.