我是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>
答案 0 :(得分:3)
要详细介绍the answer provided by 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>
答案 1 :(得分:1)
通常来说,JS中没有允许您在不知道其ID的情况下清除计时器的功能。您需要跟踪它们。
但是您可以将setTimeout
包装在另一个跟踪所有创建的计时器的函数中。
(例如,将创建的计时器的ID保存在数组中)
然后在另一个函数中重写clearTimeout
,该函数接受要清除的计时器的ID,如果未提供该ID,则清除上一个数组中的最后一个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>