Проверить, был ли сброшен тайм-аут? - PullRequest
36 голосов
/ 08 марта 2011

Мне интересно, есть ли способ узнать, установлен ли тайм-аут

var t=setTimeout("alertMsg()",3000);

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

Ответы [ 6 ]

42 голосов
/ 08 марта 2011

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

function Timeout(fn, interval) {
    var id = setTimeout(fn, interval);
    this.cleared = false;
    this.clear = function () {
        this.cleared = true;
        clearTimeout(id);
    };
}

Тогда вы можете сделать что-то вроде:

var t = new Timeout(function () {
    alert('this is a test');
}, 5000);
console.log(t.cleared); // false
t.clear();
console.log(t.cleared); // true

Моей первой идеей было заменить setTimeout и clearTimeout новыми функциями (сохранениеих старое значение в замыкании), которое изменило их аргументы, но затем я понял, что setTimeout возвращает число, которое является примитивом (и, следовательно, передается по значению).Я подумал, что если бы я собирался возвращать не примитивы, я мог бы просто сделать объект-обертку, который обеспечил бы большую гибкость.Однако этот метод может быть похож на тот, который вам нужен - если да, я могу предоставить соответствующий код, если вам нужен пример.

Надеюсь, это поможет.

20 голосов
/ 08 марта 2011

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

  • автоматическое удаление, когда время ожидания истечет естественным путем
  • опционально устанавливает область действия функции времени ожидания (а не просто выполняет в глобальной области видимости).
  • опционально передать массив аргументов в функцию тайм-аута

здесь:

function Timeout(fn, interval, scope, args) {
    scope = scope || window;
    var self = this;
    var wrap = function(){
        self.clear();
        fn.apply(scope, args || arguments);
    }
    this.id = setTimeout(wrap, interval);
}
Timeout.prototype.id = null
Timeout.prototype.cleared = false;
Timeout.prototype.clear = function () {
    clearTimeout(this.id);
    this.cleared = true;
    this.id = null;
};

[начать плагин без комментариев] О, и я использую модель-прототип для добавления методов в классы, но только потому, что я предпочитаю это, а не потому, что я чувствую, что это более правильно [конец плагина без комментариев]

8 голосов
/ 24 апреля 2013

Просто установите t на 0 (или t в вашем случае) в функции тайм-аута:

timeoutID = 0;

Если вы используете clearTimeout, для тайм-аута устанавливается значение 0, поэтому проверка на timeoutID === 0 проверит, был ли он очищен или завершен.

4 голосов
/ 08 марта 2011

Нет.Чтобы знать, вам нужно будет обнулить переменную t после вызова clearTimeout.В противном случае на самом деле нет индикатора.

И, к вашему сведению, лучше передать прямую ссылку на функцию вместо строки, которая будет вычислена как eval'd.

0 голосов
/ 13 февраля 2018

Как некоторые пользователи предлагают в комментариях, всякий раз, когда таймаут либо срабатывает (после истечения установленного времени), либо сбрасывается с помощью clearTimeout, установите его вручную на false или предпочтительно null.Затем вы можете выполнить простую проверку if, чтобы убедиться, что она активна.Также не забудьте инициализировать его как false / null, если необходимо.

Для этого создала небольшую тестовую страницу: https://codepen.io/TheJesper/pen/rJzava

0 голосов
/ 09 апреля 2013

Есть еще один способ проверить наличие тайм-аута.Значение, которое содержит тайм-аут, по умолчанию имеет числовое значение, которое увеличивается со временем.Таким образом, мы можем сделать следующее в конструкции if:

if (someBooleanValue && !parseInt(@changeToCriteriaTimeout) > 0){
  //Do something
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...