防抖和节流的区别?如何实现?应用场景有哪些?

一、是什么

本质上是优化高频率执行代码的一种手段
如浏览器的 resize、scroll、keypress、mousemove 等事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能
为了优化体验,需要对这类事件进行调用次数的限制,对此我们就可以采用防抖(debounce)和节流(throttle)的方式来减少调用频率

定义

节流:n秒内只允许一次,若在n秒内重复触发,只有一次生效
防抖:n秒后在执行该事件,若在n秒内被重复触发,则重新计时

二、代码实现

节流

function throttled(fn, delay) {
    
    
    let timer = null
    let starttime = Date.now()
    return function () {
    
    
        let curTime = Date.now() // 当前时间
        let remaining = delay - (curTime - starttime)  // 从上一次到现在,还剩下多少多余时间
        let context = this
        let args = arguments
        clearTimeout(timer)
        if (remaining <= 0) {
    
    
            fn.apply(context, args)
            starttime = Date.now()
        } else {
    
    
            timer = setTimeout(fn, remaining);
        }
    }
}

防抖

function debounce(func, wait, immediate) {
    
    

    let timeout;

    return function () {
    
    
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout); // timeout 不为null
        if (immediate) {
    
    
            let callNow = !timeout; // 第一次会立即执行,以后只有事件执行后才会再次触发
            timeout = setTimeout(function () {
    
    
                timeout = null;
            }, wait)
            if (callNow) {
    
    
                func.apply(context, args)
            }
        }
        else {
    
    
            timeout = setTimeout(function () {
    
    
                func.apply(context, args)
            }, wait);
        }
    }
}

三、区别

相同点:

  • 都可以通过使用setTimeout实现

  • 目的都是,降低回调执行频率,节省计算资源
    不同点:

  • 函数防抖,在一段连续操作结束后,处理回调,利用clearTimeout和setTimeout实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能

  • 函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次

四、应用场景

防抖在连续的事件,只需触发一次回调的场景有:

  • 搜索框搜索输入。只需用户一次输入完,再发送请求

  • 手机号、邮箱验证输入检测

    扫描二维码关注公众号,回复: 15518039 查看本文章
  • 窗口大小resize。只需窗口调整完成后,计算窗口大小。防止重复渲染
    节流在间隔一段时间执行一次回调的场景有:

  • 滚动加载,加载更多或滚动到底部监听

  • 搜索框,搜索联想功能

猜你喜欢

转载自blog.csdn.net/m0_68009075/article/details/131109076