Hai*_*ood 113 javascript timeout
如果我有一个已设置的活动超时运行var t = setTimeout("dosomething()", 5000)
,
反正有暂停和恢复吗?
Tim*_*own 243
你可以window.setTimeout
像这样包装,我认为这与你在问题中建议的类似:
var Timer = function(callback, delay) {
var timerId, start, remaining = delay;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= Date.now() - start;
};
this.resume = function() {
start = Date.now();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
};
this.resume();
};
var timer = new Timer(function() {
alert("Done!");
}, 1000);
timer.pause();
// Do some stuff...
timer.resume();
Run Code Online (Sandbox Code Playgroud)
Sea*_*ira 17
这样的事情应该可以解决问题.
function Timer(fn, countdown) {
var ident, complete = false;
function _time_diff(date1, date2) {
return date2 ? date2 - date1 : new Date().getTime() - date1;
}
function cancel() {
clearTimeout(ident);
}
function pause() {
clearTimeout(ident);
total_time_run = _time_diff(start_time);
complete = total_time_run >= countdown;
}
function resume() {
ident = complete ? -1 : setTimeout(fn, countdown - total_time_run);
}
var start_time = new Date().getTime();
ident = setTimeout(fn, countdown);
return { cancel: cancel, pause: pause, resume: resume };
}
Run Code Online (Sandbox Code Playgroud)
Tim Downs的一个略微修改的版本回答.但是,由于蒂姆回滚了我的编辑,我自己回答这个问题.我的解决方案可以使用额外的arguments
第三个(3,4,5 ...)参数并清除计时器:
function Timer(callback, delay) {
var args = arguments,
self = this,
timer, start;
this.clear = function () {
clearTimeout(timer);
};
this.pause = function () {
this.clear();
delay -= new Date() - start;
};
this.resume = function () {
start = new Date();
timer = setTimeout(function () {
callback.apply(self, Array.prototype.slice.call(args, 2, args.length));
}, delay);
};
this.resume();
}
Run Code Online (Sandbox Code Playgroud)
正如蒂姆所提到的那样,额外的参数不可用IE lt 9
,但是我有点工作,所以它也可以工作oldIE
.
用法: new Timer(Function, Number, arg1, arg2, arg3...)
function callback(foo, bar) {
console.log(foo); // "foo"
console.log(bar); // "bar"
}
var timer = new Timer(callback, 1000, "foo", "bar");
timer.pause();
document.onclick = timer.resume;
Run Code Online (Sandbox Code Playgroud)
"暂停"和"简历"在上下文中并没有多大意义setTimeout
,这是一次性的事情.你的意思是setInterval
?如果是,不,你不能暂停它,你只能取消它(clearInterval
)然后再重新安排它.规范的定时器部分中的所有这些的详细信息.
// Setting
var t = setInterval(doSomething, 1000);
// Pausing (which is really stopping)
clearInterval(t);
t = 0;
// Resuming (which is really just setting again)
t = setInterval(doSomething, 1000);
Run Code Online (Sandbox Code Playgroud)
Timeout很容易找到解决方案,但Interval有点棘手.
我想出了以下两个类来解决这个问题:
function PauseableTimeout(func, delay){
this.func = func;
var _now = new Date().getTime();
this.triggerTime = _now + delay;
this.t = window.setTimeout(this.func,delay);
this.paused_timeLeft = 0;
this.getTimeLeft = function(){
var now = new Date();
return this.triggerTime - now;
}
this.pause = function(){
this.paused_timeLeft = this.getTimeLeft();
window.clearTimeout(this.t);
this.t = null;
}
this.resume = function(){
if (this.t == null){
this.t = window.setTimeout(this.func, this.paused_timeLeft);
}
}
this.clearTimeout = function(){ window.clearTimeout(this.t);}
}
function PauseableInterval(func, delay){
this.func = func;
this.delay = delay;
this.triggerSetAt = new Date().getTime();
this.triggerTime = this.triggerSetAt + this.delay;
this.i = window.setInterval(this.func, this.delay);
this.t_restart = null;
this.paused_timeLeft = 0;
this.getTimeLeft = function(){
var now = new Date();
return this.delay - ((now - this.triggerSetAt) % this.delay);
}
this.pause = function(){
this.paused_timeLeft = this.getTimeLeft();
window.clearInterval(this.i);
this.i = null;
}
this.restart = function(sender){
sender.i = window.setInterval(sender.func, sender.delay);
}
this.resume = function(){
if (this.i == null){
this.i = window.setTimeout(this.restart, this.paused_timeLeft, this);
}
}
this.clearInterval = function(){ window.clearInterval(this.i);}
}
Run Code Online (Sandbox Code Playgroud)
这些可以这样实现:
var pt_hey = new PauseableTimeout(function(){
alert("hello");
}, 2000);
window.setTimeout(function(){
pt_hey.pause();
}, 1000);
window.setTimeout("pt_hey.start()", 2000);
Run Code Online (Sandbox Code Playgroud)
此示例将设置一个可暂停的超时(pt_hey),计划在两秒钟后发出警报,"嘿".另一个超时在一秒后暂停pt_hey.第二次超时在两秒后恢复pt_hey.pt_hey运行一秒钟,暂停一秒钟,然后恢复运行.pt_hey在三秒后触发.
现在是更棘手的间隔
var pi_hey = new PauseableInterval(function(){
console.log("hello world");
}, 2000);
window.setTimeout("pi_hey.pause()", 5000);
window.setTimeout("pi_hey.resume()", 6000);
Run Code Online (Sandbox Code Playgroud)
此示例设置一个可暂停的Interval(pi_hey),每两秒在控制台中写入"hello world".超时会在五秒后暂停pi_hey.六秒后,另一个超时恢复pi_hey.所以pi_hey将触发两次,运行一秒,暂停一秒,运行一秒,然后每2秒继续触发一次.
clearTimeout()和clearInterval()
pt_hey.clearTimeout();
并pi_hey.clearInterval();
作为清除超时和间隔的简单方法.
getTimeLeft()
pt_hey.getTimeLeft();
并且pi_hey.getTimeLeft();
将返回多少毫秒,直到下一个触发预定要发生.