JavaScript getTimeout?
window.setTimeout (и связанная с этим функция setInterval) в Javascript позволяет планировать функцию, которая будет выполняться в будущем:
id = setTimeout(function, delay);
где "delay" - это количество миллисекунд в будущем, когда вы хотите, чтобы вызываемая функция была вызвана. До истечения этого времени вы можете отменить таймер, используя:
clearTimeout(id);
Я хочу установить обновить таймер. Я хочу, чтобы иметь возможность продвигать или замедлять таймер, чтобы функция получила название x миллисекунд раньше или позже, чем первоначально планировалось.
Если бы был метод getTimeout, вы могли бы сделать что-то вроде:
originally_scheduled_time = getTimeout(id);
updateTimeout(id, originally_schedule_time + new_delay); // change the time
но насколько я могу сказать, нет ничего похожего на getTimeout или любой способ обновить существующий таймер.
Есть ли способ получить доступ к списку запланированных аварийных сигналов и изменить их?
Есть ли лучший подход?
спасибо!
Ответы
Ответ 1
Если вам действительно нужна такая функциональность, вам нужно будет написать ее самостоятельно.
Вы можете создать оболочку для вызова 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
Ответ 2
Я верю, что нет. Лучшим подходом может быть создание собственной оболочки, в которой хранятся ваши таймеры (func-ref, delay и timestamp). Таким образом, вы можете притворяться, что обновляете таймер, очищая его и рассчитывая копию с обновленной задержкой.
Ответ 3
Другая оболочка:
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!
Ответ 4
Это может быть не совсем то, что вы хотите, но взгляните в любом случае, возможно, вы можете использовать его в свою пользу.
Существует отличное решение, написанное моим бывшим коллегой, которое может создавать специальные функции обработчика, которые могут останавливать и запускать таймауты, когда это необходимо. Это наиболее широко используется, когда вам нужно создать небольшую задержку для событий наведения. Например, если вы хотите скрыть меню курсора мыши не точно в то время, когда мышь покидает его, но через несколько миллисекунд позже. Но если мышь вернется, вам нужно отменить тайм-аут.
Решение - это функция, называемая 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
});
handlers
становится объектом, который содержит две функции обработчика, которые при вызове отменяют другой таймаут.
var element = $('menu_element');
element.observe('mouseover', handlers.over);
element.observe('mouseout', handlers.out);
P.S. Для этого решения вам нужно расширить объект Function с помощью функции curry
, которая автоматически выполняется в Prototype.
Ответ 5
Одна из возможностей может быть такой:
if (this condition true)
{
setTimeout(function, 5000);
}
elseif (this condition true)
{
setTimeout(function, 10000);
}
else
{
setTimeout(function, 1000);
}
Это зависит от того, как вы строите свои условия или логику. спасибо