最经典考题-手写防抖函数

453 阅读1分钟

防抖

首先我,应该知道啥叫防抖?它有啥用呢?

debounce(fn,delay) 从字面上,防抖是防止抖动。其实,函数防抖(debounce),就是指触发事件后,在 n 秒内函数只能执行一次,如果触发事件后在 n 秒内又触发了事件,则会重新计算函数延执行时间。

作用: 比较典型的有搜索事件,用户在不断输入值时,用防抖来节约请求资源,只有最后一次回车才能返回结果。还有按钮点击事件,为了防止用户多次重复提交也会使用防抖函数。最后就是部分的电话号码输入的验证,要等停止输入后才会进行一次验证。

如果还是有点迷糊,我们来看个例子慢慢了解。

当我们没有进行防抖时,每次输入,他都会进行验证。而当我们采取防抖后,他会自动验证。 当我们没有进行防抖输入时,

我主要是从这位大佬那里学到的知识。防抖动(debounce)了解吗? - 掘金灵扁扁 (juejin.cn)

image.png 看一下代码

html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>防抖动 Demo</title>
</head>
<body>
<h1>防抖动 Demo</h1>

<label>

    <span>输入电话号码:</span>
    非防抖<input oninput="validatePhone1(event.data)"></input>
    <hr>
    <span>输入电话号码:</span>
    防抖动<input oninput="inputChange(event.data)"></input>
</label>

<script>

  let timer = null

  function inputChange (data) {
    // 不做防抖动会频繁触发校验,例如连续的输入两个字可能会触发6-7次,
    // 这种频繁程度可能不是必要的,当频繁不是必要的,那么就是资源的浪费。
    // validatePhone(data)

    // 防抖处理,连续正常的输入同样的两个字,只会触发一次校验任务。
    clearTimeout(timer)
    timer = setTimeout(() => {
      validatePhone(data)
    }, 1000)
  }

  function validatePhone (data) {
    let flag = true
    const regPhone = /^1\d{10}$/
    if (!regPhone.test(data)) {
      flag = false
      console.log('非防抖校验内容:' + data + '。手机号不正确,请输入1开头的11位手机号')
    }
    return flag
  }
  function validatePhone1 (data) {
    let flag = true
    const regPhone = /^1\d{10}$/
    if (!regPhone.test(data)) {
      flag = false
      console.log('防抖校验内容:' + data + '。手机号不正确,请输入1开头的11位手机号')
    }
    return flag
  }
</script>
</body>
</html>

手写防抖函数

 // 防抖(简单版本)
        function debounce(fn, delay) {
            let timer = null;
            clearTimeout(timer); // 下次调用时会清除上次的timer, 然后重新延迟
            timer = setTimeout(function () {
                fn();
            }, delay);
        }

        // 防抖(立即执行版本)
        function debounce(fn, wait) {
            let timer = null
            return function () {
                let args = arguments
                let now = !timer
                timer && clearTimeout(timer)
                timer = setTimeout(() => {
                    timer = null
                }, wait)
                if (now) {
                    fn.apply(this, args)
                }
            }
        }