清除上次创建的计时器对象的超时



我是javascript的新手,也是javascript定时器示例的新手。

我知道,存储计时器对某个变量(var o=setTimeout(func;1000)(的引用可以使稍后通过调用clearTimeout(o)来停止执行变得容易。

但是,如果引用没有存储在变量中,是否仍然可以在最后创建的计时器上调用clearTimeout

以下是我想通过按下停止按钮来取消计时器的示例。

<button onclick="setTimeout(helloWorld, 3000)">Start </button>
<button onclick="clearTimeout()">Stop</button>
<script>
function helloWorld() {
alert("Hello");
setTimeout(helloWorld, 3000);
}
</script>

为了详细说明Hyyan Abo Fakher提供的答案,这里有一个可能的实现:

class TimerFactory {
constructor () {
this.ids = new Set()
}
get last () {
return [...this.ids.values()].pop()
}
setTimeout (fn, ms, ...args) {
const id = setTimeout(() => {
this.ids.delete(id)
fn(...args)
}, ms)
this.ids.add(id)
return id
}
clearTimeout (id = this.last) {
this.ids.delete(id)
return clearTimeout(id)
}
}
const timer = new TimerFactory()
function helloWorld () {
console.log('Hello')
timer.setTimeout(helloWorld, 1000)
}
<button onclick="timer.setTimeout(helloWorld, 1000)">Start </button>
<button onclick="timer.clearTimeout()">Stop</button>

但是,我认为在这里使用setInterval()和保护来防止设置多个间隔会更容易、更直观:

let intervalId = null
document.querySelector('[data-action="Start"]').addEventListener('click', () => {
if (intervalId === null) {
intervalId = setInterval(() => {
console.log('Hello')
}, 1000)
}
})
document.querySelector('[data-action="Stop"]').addEventListener('click', () => {
clearTimeout(intervalId)
intervalId = null
})
[data-action]:before {
content: attr(data-action);
}
<button data-action="Start"></button>
<button data-action="Stop"></button>

一般来说,JS中没有任何函数允许您在不知道计时器ID的情况下清除计时器。您需要跟踪它们。

但是,您可以将setTimeout封装在另一个函数中,该函数可以跟踪所有创建的计时器。(例如,将创建的计时器的ID保存在阵列中(则在另一个函数中覆盖CCD_ 6,该函数接受要清除的定时器的ID

const timers = []
const setTimeout = function(func, time) {
const id = window.setTimeout(() => {
const index = timers.indexOf(id);
if (index > -1) timers.splice(index, 1);
func()
}, time);
timers.push(id);
return id;
}
const clearTimeout = function(id) {
if (id) {
window.clearTimeout(id)
const index = timers.indexOf(id)
if (index > -1) timers.splice(index, 1);
} else if (timers.length > 0) {
const lastTimer = timers[timers.length - 1]
window.clearTimeout(lastTimer)
timers.splice(-1, 1)
}
}
function helloWorld() {
console.log("Hello");
setTimeout(helloWorld, 500);
}
<button onclick="setTimeout(helloWorld, 3000)">Start </button>
<button onclick="clearTimeout()">Stop</button>

最新更新