手写函数防抖和函数节流

133 阅读3分钟

函数节流

节流(throttling)是一种常见的性能优化技术,用于限制某个函数在一定时间间隔内的执行次数。使用JavaScript手写一个节流函数可以按照以下步骤进行实现:

function throttle(func, delay) {
  let timeoutId;
  let lastExecTime = 0;

  return function(...args) {
    const currentTime = Date.now();
    const timeSinceLastExec = currentTime - lastExecTime;

    const execute = () => {
      func.apply(this, args);
      lastExecTime = currentTime;
    };

    if (!timeoutId) {
      execute();
      timeoutId = setTimeout(() => {
        timeoutId = null;
        if (timeSinceLastExec >= delay) {
          execute();
        }
      }, delay);
    }
  };
}

在上述代码中,我们定义了throttle函数,该函数接收两个参数:func(需要节流的函数)和 delay(时间间隔,单位为毫秒)。

在函数内部,我们使用了闭包来维护了一个timeoutId变量和lastExecTime变量。timeoutId用于存储定时任务的标识符,lastExecTime用于记录上次执行函数的时间。

通过返回一个新的函数,我们实现了节流功能。每当新函数被调用时,首先获取当前时间(currentTime),然后计算距离上次函数执行的时间间隔(timeSinceLastExec)。

接下来,我们定义了内部函数execute,它用于执行func函数并更新lastExecTime为当前时间。

在主函数内部,我们进行了一些条件判断:如果timeoutId不存在(表示没有定时任务在执行),则直接执行func函数,并设置一个定时任务。定时任务的作用是用于清空timeoutId并判断距离上次执行的时间间隔是否大于等于delay,如果是则再次调用func函数。

这样,通过在一定时间间隔内只执行一次函数,我们实现了节流。

使用示例:

function handleResize() {
  console.log('Resized');
}

const throttledResize = throttle(handleResize, 200);

window.addEventListener('resize', throttledResize);

在此示例中,我们定义了handleResize作为需要节流的函数,并通过throttle函数创建了throttledResize节流函数。然后,我们将throttledResize函数绑定到resize事件上,这样在窗口大小改变时,handleResize函数最多每200毫秒执行一次。

函数防抖

防抖(debouncing)是一种常见的性能优化技术,用于限制某个函数在一定时间间隔内的连续执行次数。使用JavaScript手写一个防抖函数可以按照以下步骤进行实现:

function debounce(func, delay) {
  let timeoutId;

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

    timeoutId = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

在上述代码中,我们定义了debounce函数,该函数接收两个参数:func(需要防抖的函数)和 delay(时间间隔,单位为毫秒)。

在函数内部,我们使用了闭包来维护了一个timeoutId变量。timeoutId用于存储定时任务的标识符。

通过返回一个新的函数,我们实现了防抖功能。每当新函数被调用时,首先清除之前的定时任务(如果有的话),然后创建一个新的定时任务,在指定的时间间隔后执行func函数。

这样,通过限制函数在连续调用中只执行最后一次,我们实现了防抖。

使用示例:

function handleInput(event) {
  console.log(event.target.value);
}

const debouncedInput = debounce(handleInput, 300);

document.getElementById('input').addEventListener('input', debouncedInput);

在此示例中,我们定义了handleInput作为需要防抖的函数,并通过debounce函数创建了debouncedInput防抖函数。然后,我们将debouncedInput函数绑定到一个输入框的input事件上,当用户输入内容时,handleInput函数将在最后一次输入后300毫秒内执行。