LiuL0703 / blog

Home Page:https://liul0703.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

函数节流(throttle)与去抖(debounce)

LiuL0703 opened this issue · comments

函数去抖(debounce)

函数去抖核心是指:为了不让一个函数单位时间内执行次数太多 从而导致性能问题 限制其在一定时间的连续的函数调用只让其执行一次

应用场景

  • resize/scroll 触发统计事件
  • 文本输入验证 (输入完成后只验证一次)
  • 监听滚动事件判断是否到底部以自动加载更多 (用户停止滚动 判断是否到底部)

基本**

某些代码不可以在没有间断的情况连续重复执行,第一次调用函数创建一个定时器 在指定的时间间隔之后运行代码 当第二次调用该函数时 就会清除前一次的定时器并设置另外一个 如果前一个定时器已经执行过了这个操作就没有意义了 然而如果前一个定时器尚未执行 其实就是将其替换为一个新型的定时器 目的是只有在执行函数的请求停止一段时间后才执行(高程3 P614)
经典实现代码如下:

function debounce(fn,time){
    var timer;
    return function(){
        clearTimeout(timer);
        var context = this;
        var args = arguments;
        timer = setTimeout(function(){
            fn.apply(context,args);
        },time)
    }
}

函数去抖在一段时间只执行一次,而函数节流则是间隔时间段执行 具体如下

函数节流(throttle)

函数节流的核心是指:为了不让一个函数执行的太频繁 减少一些过快的调用 降低函数触发的回调频率

应用场景

  • DOM元素的拖拽(mousemove)
  • 计算鼠标移动的距离(mousemove)
  • Canvas模拟画板(mousemove)
  • 搜索联想(keyup)
  • 射击游戏的mousedown/keydown(单位时间)
  • 监听滚动事件判断是否到底部以自动加载更多 (页面滚动一次就间隔判断一次)
// 定时器实现
function throttle(fn,wait){
    var timer;

    return function(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                fn.apply(context,args);
            },wait)
        }
    }
}

// 时间戳实现
function throttle(fn,wait){
    var timer;
    var prev = 0;

    return function(){
        var args = arguments;
        var now = +new Date();
        if(now - prev > wait){
            fn.apply(this,args);
            prev = now;
        }
    }
}

// swr

function throttle(fn, wait){
    let pending = false;

    return (...args) => {
        if(pending) return;
        pending = true;
        fn(...args);
        setTimeout(()=> (pending = false), wait);
    }
}