请帮助我解决问题,我们如何返回输入功能的反跳版本。 检查以下代码:
const steven = () => {console.log('steven')}
const debounce = (fn, timeLimit) => {
// what should come here?
}
const debouncedSteeven = debounce(steven, 5000) // returns a debounced version of the input function
window.addEventListener('scroll', debouncedSteeven);
答案 0 :(得分:1)
如果我理解正确,那么您希望函数在没有scroll
毫秒以上的X
事件的情况下执行。在这种情况下,一种解决方案是使用setTimeout()
和clearTimeout()
。因此,每次调用去抖动功能时,timeout
都会被重置(如果已存在)。实现将是这样的:
// Object to hold the timers by function names.
let timers = {};
const steven = () => {console.log('steven')};
const debounce = (fn, timeLimit) =>
{
return () =>
{
if (timers[fn.name])
clearTimeout(timers[fn.name]);
timers[fn.name] = setTimeout(fn, timeLimit);
}
}
const debouncedSteeven = debounce(steven, 5000);
window.addEventListener('scroll', debouncedSteeven);
.as-console {background-color:black !important; color:lime;}
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
如果两个X
事件之间的间隔为scroll
毫秒,而您想执行该函数,则可以尝试以下操作:
// Object to hold last time a debounced method is called.
let lastExec = {};
const steven = () => {console.log('steven')};
const debounce = (fn, timeLimit) =>
{
return () =>
{
if (new Date().getTime() - lastExec[fn.name] > timeLimit)
fn();
lastExec[fn.name] = new Date().getTime();
}
}
const debouncedSteeven = debounce(steven, 5000);
window.addEventListener('scroll', debouncedSteeven);
.as-console {background-color:black !important; color:lime;}
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
<p>text</p>
答案 1 :(得分:1)
您可以在高阶函数中使用setTimeout
来调度该函数的执行,但是如果再次调用该函数,则可以取消。
此外,您可以存储和传递调用时的上下文和参数,并使用那些参数来调用去抖动的函数,以免丢失它们。这样一来,您不仅可以将反跳功能应用于任何功能,不仅可以应用于不使用this
并且不带任何参数的功能:
function debounce(fn, limit = 0) {
//this will hold the timer identifier from setTimeout
let timeId;
//return a debounced function
return function _debounced() {
//unschedule any previous execution
clearTimeout(timeId);
//store the arguments
const args = arguments;
//store the context
let ctx = this;
//schedule a new execution after the given time limit
timeId = setTimeout(function() {
//run the function with the context and arguments passed
fn.apply(ctx, args);
}, limit);
}
}
//using parameters
function add(a, b) {
console.log("adding", a, b);
console.log("result", a + b);
}
const debouncedAdd = debounce(add, 1000);
debouncedAdd(1, 2);
debouncedAdd(3, 4);
debouncedAdd(5, 6); //only this gets executed
//using context
const person = {
name: "Alice",
sayHello: debounce(function sayHello() {
console.log("hello, my name is:", this.name)
}, 1000)
}
person.sayHello();
person.name = "Bob";
person.sayHello();
person.name = "Carol";
person.sayHello(); //only this gets executed
答案 2 :(得分:-1)
查看setTimeout
,它基本上可以满足您的要求。
const debounce = (fn, timeLimit) => () => {
clearTimeout(this.timeout);
this.timeout = setTimeout(fn, timeLimit);
};
let myFunc = () => console.log('yo');
let myFuncDebounced = debounce(myFunc);
myFuncDebounced();
myFuncDebounced();
console.log('this will print first cause this aint Tha BOUNCE d!!!');
答案 3 :(得分:-1)
我认为最好的解决方案是使用rxjs 首先使用npm或yarn安装rxjs。 然后通过滚动事件创建一个可观察的对象,并将反跳操作符和管道函数传递给计时器操作符,并在计时器函数中将其从rxjs导入。
fromEvent(window, 'scroll')
.pipe(debounce(() => timer(1000))
.subscribe(v => console.log('scrolled'))
此代码将以去抖时间1000毫秒= 1秒记录“滚动”。 建议您在组件的生命周期或代码结束时取消分配,以防止内存泄漏