返回输入函数的反跳版本

时间:2019-04-18 19:22:50

标签: javascript

请帮助我解决问题,我们如何返回输入功能的反跳版本。 检查以下代码:

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);

4 个答案:

答案 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秒记录“滚动”。 建议您在组件的生命周期或代码结束时取消分配,以防止内存泄漏

相关问题