JavaScript getTimeout?

window.setTimeout (и связанный setInterval) функция в JavaScript позволяет Вам планировать функцию, которая будет выполняться когда-то в будущем:

id = setTimeout(function, delay);

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

clearTimeout(id);

То, что я хочу, должно обновить таймер. Я хочу быть в состоянии усовершенствовать или задержать таймер так, чтобы функция была вызвана x миллисекунды рано или поздно, чем первоначально запланированный.

Если бы был getTimeout метод, то Вы могли бы сделать что-то как:

originally_scheduled_time = getTimeout(id);
updateTimeout(id, originally_schedule_time + new_delay);  // change the time

но насколько я могу сказать, что нет ничего как getTimeout или любой способ обновить существующий таймер.

Существует ли способ получить доступ к списку запланированных предупреждений и изменить их?

Существует ли лучший подход?

Спасибо!

17
задан jensgram 25 December 2009 в 07:13
поделиться

5 ответов

Если вам действительно нужен такой функционал, вам нужно будет написать его самому.

Вы можете создать обертку для вызова setTimeout, которая вернет объект, который вы можете использовать для "откладывания" таймера:

function setAdvancedTimer(f, delay) {
  var obj = {
    firetime: delay + (+new Date()), // the extra + turns the date into an int 
    called: false,
    canceled: false,
    callback: f
  }; 
  // this function will set obj.called, and then call the function whenever
  // the timeout eventually fires.
  var callfunc = function() { obj.called = true; f(); }; 
  // calling .extend(1000) will add 1000ms to the time and reset the timeout.
  // also, calling .extend(-1000) will remove 1000ms, setting timer to 0ms if needed
  obj.extend = function(ms) {
    // break early if it already fired
    if (obj.called || obj.canceled) return false; 
    // clear old timer, calculate new timer
    clearTimeout(obj.timeout);
    obj.firetime += ms;
    var newDelay = obj.firetime - new Date(); // figure out new ms
    if (newDelay < 0) newDelay = 0;
    obj.timeout = setTimeout(callfunc, newDelay);
    return obj;
  };
  // Cancel the timer...  
  obj.cancel = function() {
    obj.canceled = true;
    clearTimeout(obj.timeout);
  };
  // call the initial timer...
  obj.timeout = setTimeout(callfunc, delay);
  // return our object with the helper functions....
  return obj;
}

var d = +new Date();
var timer = setAdvancedTimer(function() { alert('test'+ (+new Date() - d)); }, 1000);

timer.extend(1000);
// should alert about 2000ms later
14
ответ дан 30 November 2019 в 14:00
поделиться

Другая обертка:

function SpecialTimeout(fn, ms) {
    this.ms = ms;
    this.fn = fn;
    this.timer = null;
    this.init();
}

SpecialTimeout.prototype.init = function() {
    this.cancel();
    this.timer = setTimeout(this.fn, this.ms);
    return this;
};

SpecialTimeout.prototype.change = function(ms) {
    this.ms += ms;
    this.init();
    return this;
};

SpecialTimeout.prototype.cancel = function() {
    if ( this.timer !== null ) {
        clearTimeout(this.timer);
        this.timer = null;
    }
    return this;
};

Использование:

var myTimer = new SpecialTimeout(function(){/*...*/}, 10000);

myTimer.change(-5000); // Retard by five seconds
myTimer.change(5000); // Extend by five seconds
myTimer.cancel(); // Cancel
myTimer.init(); // Restart

myTimer.change(1000).init(); // Chain!
2
ответ дан 30 November 2019 в 14:00
поделиться

Одна возможность может быть такой:

if (this condition true)
{
  setTimeout(function, 5000);
}
elseif (this condition true)
{
  setTimeout(function, 10000);
}
else
{
  setTimeout(function, 1000);
}

Это зависит от того, как вы строите свои условия или от логики. Спасибо

.
-2
ответ дан 30 November 2019 в 14:00
поделиться

Думаю, что нет. Лучшим подходом может быть написание собственной обертки, в которой хранятся ваши таймеры (func-ref, delay, timestamp). Таким образом, вы можете сделать вид, что обновляете таймер, очищая его и вычисляя копию с обновленной задержкой.

4
ответ дан 30 November 2019 в 14:00
поделиться

Это может быть не совсем то, что вы хотите, но посмотрите в любом случае, может быть, вы можете использовать его в своих интересах.

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

Решение - функция getDelayedHandlers. Например, у вас есть функция, которая показывает и скрывает меню

function handleMenu(show) {
    if (show) {
        // This part shows the menu
    } else {
        // This part hides the menu
    }
}

Вы можете создать для него отложенные обработчики, сделав это:

var handlers = handleMenu.getDelayedHandlers({
    in: 200, // 'in' timeout
    out: 300, // 'out' timeout
});

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

var element = $('menu_element');
element.observe('mouseover', handlers.over);
element.observe('mouseout', handlers.out);

P.S. Для того, чтобы это решение сработало, необходимо расширить объект Function функцией curry, что автоматически делается в Prototype.

.
0
ответ дан 30 November 2019 в 14:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: