window.setInterval(function(){
//do stuff
}, milisec);
有没有办法随意停止这个间隔,并从它持续的地方恢复它?比如说,代码每5秒运行一次。我在第二秒的中间停止它,当恢复时,我希望它运行剩余的3秒并且每隔5秒继续运行。试。
答案 0 :(得分:26)
试试这个:
1-当您想要pause
计时器时,计算剩余的毫秒并将其存储在某处,然后拨打clearInterval
。
2-当你想要resume
计时器时,只需拨打setTimeout
,将上一步中存储的剩余时间作为参数。
3-在setTimeout
的回调中,您应该再次致电setInterval
。
更新:这是你想要的,javascript: pause setTimeout();的更改版本归功于@Felix Kling
function IntervalTimer(callback, interval) {
var timerId, startTime, remaining = 0;
var state = 0; // 0 = idle, 1 = running, 2 = paused, 3= resumed
this.pause = function () {
if (state != 1) return;
remaining = interval - (new Date() - startTime);
window.clearInterval(timerId);
state = 2;
};
this.resume = function () {
if (state != 2) return;
state = 3;
window.setTimeout(this.timeoutCallback, remaining);
};
this.timeoutCallback = function () {
if (state != 3) return;
callback();
startTime = new Date();
timerId = window.setInterval(callback, interval);
state = 1;
};
startTime = new Date();
timerId = window.setInterval(callback, interval);
state = 1;
}
用法:
var timer = new IntervalTimer(function () {
alert("Done!");
}, 5000);
window.setTimeout(function () {
timer.pause();
window.setTimeout(function () {
timer.resume();
}, 5000);
}, 2000);
答案 1 :(得分:4)
为了背负Alireza的答案,这里是一个ES6类,它可以通过更多功能执行相同的操作,并且不会立即启动。您可以设置定时器在自动停止之前触发的最大次数,并在下次设置为关闭之前暂停和恢复任意次数。
export default class IntervalTimer{
constructor(name, callback, interval, maxFires = null){
this.remaining = 0;
this.state = 0; // 0 = idle, 1 = running, 2 = paused, 3= resumed
this.name = name;
this.interval = interval; //in ms
this.callback = callback;
this.maxFires = maxFires;
this.pausedTime = 0; //how long we've been paused for
this.fires = 0;
}
proxyCallback(){
if(this.maxFires != null && this.fires >= this.maxFires){
this.stop();
return;
}
this.lastTimeFired = new Date();
this.fires++;
this.callback();
}
start(){
this.log.info('Starting Timer ' + this.name);
this.timerId = setInterval(() => this.proxyCallback(), this.interval);
this.lastTimeFired = new Date();
this.state = 1;
this.fires = 0;
}
pause(){
if (this.state != 1 && this.state != 3) return;
this.log.info('Pausing Timer ' + this.name);
this.remaining = this.interval - (new Date() - this.lastTimeFired) + this.pausedTime;
this.lastPauseTime = new Date();
clearInterval(this.timerId);
clearTimeout(this.resumeId);
this.state = 2;
}
resume(){
if (this.state != 2) return;
this.pausedTime += new Date() - this.lastPauseTime;
this.log.info(`Resuming Timer ${this.name} with ${this.remaining} remaining`);
this.state = 3;
this.resumeId = setTimeout(() => this.timeoutCallback(), this.remaining);
}
timeoutCallback(){
if (this.state != 3) return;
this.pausedTime = 0;
this.proxyCallback();
this.start();
}
stop(){
if(this.state === 0) return;
this.log.info('Stopping Timer %s. Fired %s/%s times', this.name, this.fires, this.maxFires);
clearInterval(this.timerId);
clearTimeout(this.resumeId);
this.state = 0;
}
//set a new interval to use on the next interval loop
setInterval(newInterval){
this.log.info('Changing interval from %s to %s for %s', this.interval, newInterval, this.name);
//if we're running do a little switch-er-oo
if(this.state == 1){
this.pause();
this.interval = newInterval;
this.resume();
}
//if we're already stopped, idle, or paused just switch it
else{
this.interval = newInterval;
}
}
setMaxFires(newMax){
if(newMax != null && this.fires >= newMax){
this.stop();
}
this.maxFires = newMax;
}
}
答案 2 :(得分:2)
你应该只需要带有go和stop的setTimeout - http://jsfiddle.net/devitate/QjdUR/1/
var cnt = 0;
var fivecnt = 0;
var go = false;
function timer() {
if(!go)
return;
cnt++;
if(cnt >= 5){
cnt=0;
everyFive();
}
jQuery("#counter").text(cnt);
setTimeout(timer, 1000);
}
function everyFive(){
fivecnt++;
jQuery("#fiver").text(fivecnt);
}
function stopTimer(){
go = false;
}
function startTimer(){
go = true;
timer();
}