[JavaScript] 防抖函数和节流函数

前言

防抖函数和节流函数的区别,可以查看这篇文章,写得比较好:面试官:什么是防抖和节流?有什么区别?如何实现?

防抖(debounce)

防抖函数:主要目的是在一定时间内,如果函数多次被调用,只执行最后一次调用的函数。

执行最后一次是什么意思?如果我频繁点击10次,也就是前面9次都不会执行,只执行最后一次对吗?

假设设置了 delay 为 500ms,并且在短时间内连续点击了10次。

当第一次点击时,防抖函数会设置一个计时器,计划在 500ms 后执行对应的 func。但如果在 500ms 内再次点击,防抖函数会清除上次的计时器,并重新设置一个新的 500ms 计时器。这意味着上次的 func 调用会被取消,不会执行。这个过程会不断重复,每次新的点击都会清除之前的计时器,并重新开始 500ms 的倒计时。

只有当停止点击且最后一次点击后的500ms内不再有新的点击时,防抖函数才会执行这最后一次点击对应的 func。所以,前9次点击都不会触发 func 的执行,只有在点击停止后的 500ms,才会执行最后一次点击的操作。

file:[debounce.ts]
function debounce(func, delay) {
  let timer;

  return function(...args) {
    clearTimeout(timer);
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

节流(throttle)

节流函数:节流函数确保在一段时间内,即使触发事件多次,该函数也只会执行一次。

时间戳实现版本:当前时间戳减去上一次点击执行记录的时间戳,如果大于等于定义的 delay 毫秒数就允许执行操作。

file:[throttle.ts]
function throttle(func, delay) {
  let lastExecTime = 0;

  return function (...args) {
    const now = Date.now();
    if (now - lastExecTime >= delay) {
      func.apply(this, args);
      lastExecTime = now;
    }
  };
}

定时器实现版本:timeoutId 为 null 说明上一个定时器还在,忽略本次操作不执行。当到达了 wait 毫秒数之后执行回调函数,执行完成清除定时器,允许下一次执行。

function throttle(func, wait) {
    let timer = null;

    return function (...args) {
        if (timeoutId) return;

        timer = setTimeout(() => {
            func.apply(this, args);
            timer = null;
        }, wait);
    };
}
posted @ 2023-11-01 00:40  Himmelbleu  阅读(6)  评论(0编辑  收藏  举报