防抖与节流

97 阅读2分钟

背景:学习梳理,便于以后查阅
参考文章

防抖

1. 什么是防抖?

  • 所谓防抖,就是指触发事件后 n 秒后才执行函数,如果在 n 秒内又触发了事件,则会重新计算函数执行时间

2. 应用防抖

非立即执行版本

    function debounce(func, delay) {
        let timeout
        return function () {
            let _this = this
            let args = [...arguments]
            if (timeout) {
                clearTimeout(timeout)
            }
            timeout = setTimeout(() => {
                func.apply(_this, args)
            }, delay)
        }
    }
  • 暂存 this 和 参数。

  • 功能函数通过调用apply方法将debounce 函数最终返回的函数 this 指向绑定给自身。

  • 不管是setTimeout还是setInterval,都会有一个返回值。这个返回值是一个数字,代表当前是在浏览器中设置的第几个定时器(返回的是定时器序号)。如果在编辑器返回值可能是个对象。

  • 每次触发调用防抖函数,如果之前的定时器(以定时器序号作为标识符)还在。就清除前面一个定时器,并开启一个新的定时器。

  • 定时器即使清除了,其返回值也不会清除,之后设置定时器的返回值也会在其返回值的基础上继续向后排。

节流

1. 什么是节流

  • 所谓节流,就是指连续触发事件但是在n秒中之执行一次函数。节流会稀释函数的执行频率

2. 应用节流

    function throttle(func, delay) {
        let timeout
        return function () {
            let _this = this
            let args = [...arguments]
            if (!timeout) {
               timeout = setTimeout(() => {
                   timeout = null
                   func.apply(_this, args)
               }, delay)
            }
        }
    }
  • 第一次调用节流函数,还没有定时器,创建一个定时器,并在时间间隔结束时触发功能函数

  • 在时间间隔内再次调用节流函数,由于定时器已经存在,不响应

  • 当时间间隔结束后将本定时器标识符timeout清除,再创建一个定时器。

  • 由于定时器标识符timeout被设置为null,再次调用节流函数便可再次触发。