JavaScript怎么实现underscore防抖

发布时间:2022-10-22 14:47:06 作者:iii
来源:亿速云 阅读:123

JavaScript怎么实现underscore防抖

目录

  1. 什么是防抖
  2. 防抖的应用场景
  3. underscore库简介
  4. underscore防抖的实现原理
  5. 手写实现underscore防抖
  6. 防抖的优化与扩展
  7. 总结

什么是防抖

防抖(Debounce)是一种常见的前端优化技术,主要用于限制某个函数在短时间内被频繁调用。防抖的核心思想是:在事件被触发后,等待一段时间(例如200ms),如果在这段时间内事件没有被再次触发,则执行函数;如果在这段时间内事件被再次触发,则重新计时。

举个例子,假设我们有一个搜索框,用户在输入时会触发搜索请求。如果用户连续输入多个字符,我们不希望每次输入都发送请求,而是希望用户停止输入一段时间后再发送请求。这时就可以使用防抖技术。

防抖的应用场景

防抖技术在前端开发中有广泛的应用场景,以下是一些常见的例子:

  1. 搜索框输入:用户在搜索框中输入内容时,触发搜索请求。使用防抖可以避免用户每输入一个字符就发送一次请求,而是在用户停止输入一段时间后再发送请求。

  2. 窗口大小调整:当用户调整浏览器窗口大小时,可能会触发一些布局调整的函数。使用防抖可以避免在用户连续调整窗口大小时频繁触发这些函数。

  3. 按钮点击:在某些情况下,用户可能会连续点击按钮,导致多次触发点击事件。使用防抖可以确保按钮点击事件只触发一次。

  4. 滚动事件:当用户滚动页面时,可能会触发一些与滚动相关的函数。使用防抖可以避免在用户连续滚动时频繁触发这些函数。

underscore库简介

underscore 是一个JavaScript实用库,提供了许多常用的函数式编程工具,如mapreducefilter等。underscore库还提供了一个非常实用的debounce函数,用于实现防抖功能。

underscore的debounce函数可以让我们轻松地为某个函数添加防抖功能,而不需要手动实现复杂的逻辑。

underscore防抖的实现原理

underscore的debounce函数实现防抖的核心原理是通过setTimeoutclearTimeout来控制函数的执行时机。具体来说,当事件被触发时,debounce函数会启动一个定时器,如果在定时器到期之前事件再次被触发,则清除之前的定时器并重新启动一个新的定时器。只有当定时器到期且事件没有被再次触发时,才会执行目标函数。

underscore的debounce函数还支持一些可选参数,如immediate,用于控制是否在事件触发时立即执行函数,而不是等待定时器到期。

手写实现underscore防抖

为了更好地理解underscore的防抖实现,我们可以尝试手写一个类似的debounce函数。以下是手写实现的代码:

function debounce(func, wait, immediate) {
  let timeout;

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

    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
}

代码解析

  1. 参数说明

    • func:需要防抖的目标函数。
    • wait:等待时间,单位为毫秒。
    • immediate:是否在事件触发时立即执行函数。
  2. timeout变量

    • timeout用于存储定时器的ID,以便在事件再次触发时清除之前的定时器。
  3. 返回的函数

    • debounce函数返回一个新的函数,这个函数会在事件触发时被调用。
  4. context和args

    • context保存了目标函数的this上下文。
    • args保存了目标函数的参数。
  5. later函数

    • later函数会在定时器到期时执行。如果immediatefalse,则调用目标函数。
  6. callNow变量

    • callNow用于判断是否立即执行目标函数。如果immediatetruetimeoutnull,则立即执行目标函数。
  7. clearTimeout和setTimeout

    • clearTimeout(timeout)用于清除之前的定时器。
    • setTimeout(later, wait)用于启动一个新的定时器。
  8. callNow判断

    • 如果callNowtrue,则立即执行目标函数。

使用示例

function onResize() {
  console.log('Window resized');
}

window.addEventListener('resize', debounce(onResize, 200));

在这个例子中,onResize函数会在用户停止调整窗口大小200ms后执行。

防抖的优化与扩展

虽然上面的debounce函数已经可以满足大部分需求,但在某些情况下,我们可能需要对防抖功能进行一些优化或扩展。

1. 取消防抖

在某些情况下,我们可能需要在防抖函数执行之前取消它。例如,用户在搜索框中输入内容时,如果用户清空了搜索框,我们可能希望取消之前的搜索请求。

为了实现这个功能,我们可以在debounce函数中添加一个cancel方法:

function debounce(func, wait, immediate) {
  let timeout;

  const debounced = function() {
    const context = this;
    const args = arguments;

    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };

  debounced.cancel = function() {
    clearTimeout(timeout);
    timeout = null;
  };

  return debounced;
}

使用示例:

const debouncedResize = debounce(onResize, 200);
window.addEventListener('resize', debouncedResize);

// 取消防抖
debouncedResize.cancel();

2. 立即执行并防抖

在某些情况下,我们可能希望事件触发时立即执行函数,然后在等待时间内防抖。例如,用户在搜索框中输入内容时,立即显示搜索结果,然后在用户停止输入一段时间后再更新搜索结果。

为了实现这个功能,我们可以修改debounce函数的实现:

function debounce(func, wait, immediate) {
  let timeout;

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

    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (callNow) func.apply(context, args);
  };
}

使用示例:

function onInput() {
  console.log('Input changed');
}

const input = document.querySelector('input');
input.addEventListener('input', debounce(onInput, 200, true));

在这个例子中,onInput函数会在用户输入时立即执行,然后在用户停止输入200ms后再执行一次。

3. 防抖与节流的结合

防抖和节流(Throttle)是两种常见的前端优化技术。防抖的核心是等待一段时间后再执行函数,而节流的核心是在一段时间内只执行一次函数。

在某些情况下,我们可能需要结合防抖和节流的特性。例如,用户在滚动页面时,我们希望每隔一段时间执行一次函数,但如果用户停止滚动,则立即执行函数。

为了实现这个功能,我们可以结合防抖和节流的实现:

function debounceThrottle(func, wait, immediate) {
  let timeout;
  let lastExec = 0;

  return function() {
    const context = this;
    const args = arguments;
    const now = Date.now();

    const later = function() {
      timeout = null;
      if (!immediate) func.apply(context, args);
    };

    const callNow = immediate && !timeout;

    clearTimeout(timeout);
    timeout = setTimeout(later, wait);

    if (now - lastExec >= wait) {
      func.apply(context, args);
      lastExec = now;
    } else if (callNow) {
      func.apply(context, args);
    }
  };
}

使用示例:

function onScroll() {
  console.log('Page scrolled');
}

window.addEventListener('scroll', debounceThrottle(onScroll, 200, true));

在这个例子中,onScroll函数会在用户滚动页面时每隔200ms执行一次,但如果用户停止滚动,则立即执行一次。

总结

防抖是一种非常实用的前端优化技术,可以有效地减少函数的频繁调用,提升页面性能。通过手写实现underscore的debounce函数,我们可以更好地理解防抖的实现原理,并根据实际需求进行优化和扩展。

在实际开发中,我们可以根据具体的应用场景选择合适的防抖策略,并结合节流等技术进一步提升用户体验。希望本文对你理解和使用防抖技术有所帮助!

推荐阅读:
  1. javascript实现函数防抖与节流
  2. JavaScript中怎么实现防抖和节流

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

javascript underscore

上一篇:Angular怎么重构数组字段

下一篇:Vue如何实现横向轮播图效果

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》