我在https://www.youtube.com/watch?v=cjIswDCKgu0&t=429s YouTube上观看了这个视频;
我只想做一个简单的debounce函数。但是这段代码不能在我的设备上正常工作。请帮助。
let debounceTimes = 0;
// this code does not work as intended
let timeout; // if I make it global it works just fine
// but I don't want to do that for obvious reasons
function debounce(cb, delay = 100) {
// let timeout; // this is being reinitialized
// only if I could do something like this
// static timeout;
// to avoid re-initializing the variable
// return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
cb();
}, delay);
// }
}
window.addEventListener("mousemove", () => {
// console.log("hello");
// document.getElementById("debounce").innerText++;
debounce(
() => {
debounceTimes++;
document.getElementById("debounce").innerText = String(debounceTimes);
}, 100);
});
在JS中,当你想让一个变量私有到一个函数中,但又不在它的作用域中时,一个好的模式是使用闭包和IIFE:
const debounce = (function() {
let debounceTimes = 0;
let timeout; // if I make it global it works just fine
// but I don't want to do that for obvious reasons
return (cb, delay = 100) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
cb();
console.log("Count:", debounceTimes)
debounceTimes++
}, delay);
}
})()
window.onmousemove = () => debounce(() => console.log("Debounced"),200)
在本例中,这是不可能的,因为当事件被触发时,它只运行创建内部变量的debounce
函数。要避免重新初始化变量,可以:
-
在全局作用域中创建变量
-
创建另一个返回debounce函数的函数(因此超时隐藏在函数作用域中)
let debounceTimes = 0;
function getDebounce() {
let timeout;
function debounce(cb, delay = 100) {
clearTimeout(timeout);
timeout = setTimeout(() => {
cb();
}, delay);
}
return debounce;
}
const debounce = getDebounce();
window.addEventListener('mousemove', () => {
debounce(() => {
debounceTimes++;
document.getElementById('debounce').innerText = String(debounceTimes);
}, 100);
});
我最终创建了一个带有静态方法和变量的类,因为它类似于c++的做事方式。但我更喜欢@Tomasz Staszkiewicz的回答。他在函数内部编写了另一个函数来实现这一点。
class ignoreInput {
static #timeout;
static debounce (cb, delay = 100) {
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
cb();
}
, delay);
}
static throttle (cb, delay = 100) {
// some code
}
};
当我看到你不使用timeout变量的debounce函数,然后尝试它作为debounce函数的参数…
let debounceTimes = 0;
// this code does not work as intended
// if I make it global it works just fine
// but I don't want to do that for obvious reasons
function debounce(timeout, cb, delay = 100) {
// let timeout; // this is being reinitialized
// only if I could do something like this
// static timeout;
// to avoid re-initializing the variable
// return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
cb();
}, delay);
// }
}
window.addEventListener("mousemove", () => {
// console.log("hello");
// document.getElementById("debounce").innerText++;
debounce(
() => {
debounceTimes++;
document.getElementById("debounce").innerText = String(debounceTimes);
}, 100);
});
Run code snippetHide resultsExpand snippet