防抖和节流

underscorejs库:https://www.underscorejs.cn/debounce

  • _.debounce(function, wait, [immediate])
    返回 function 函数的防反跳版本, 将延迟函数的执行(真正的执行)在函数最后一次调用时刻的 wait 毫秒之后. 对于必须在一些输入(多是一些用户操作)停止到达之后执行的行为有帮助。 例如: 渲染一个 Markdown 格式的评论预览, 当窗口停止改变大小之后重新计算布局, 等等.
    在 wait 间隔结束时,将使用最近传递给 debounced(去抖动)函数的参数调用该函数。
    传参 immediate 为 true, debounce 会在 wait 时间间隔的开始调用这个函数 。(注:并且在 waite 的时间之内,不会再次调用。)在类似不小心点了提交按钮两下而提交了两次的情况下很有用。
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

如果需要取消预定的 debounce ,可以在 debounce 函数上调用 .cancel()。

  • _.throttle(function, wait, [options])
    创建并返回一个像节流阀一样的函数,当重复调用函数的时候,至少每隔 **wait **毫秒调用一次该函数。对于想控制一些触发频率较高的事件有帮助。

默认情况下,throttle 将在你调用的第一时间尽快执行这个 function,并且,如果你在** wait **周期内调用任意次数的函数,都将尽快的被覆盖。如果你想禁用第一次首先执行的话,传递{leading: false},还有如果你想禁用最后一次执行的话,传递{trailing: false}。

var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

如果需要取消预定的 throttle ,可以在 throttle 函数上调用 .cancel()。

function restArguments(func, startIndex) {
  startIndex = startIndex == null ? func.length - 1 : +startIndex;
  return function() {
    var length = Math.max(arguments.length - startIndex, 0),
        rest = Array(length),
        index = 0;
    for (; index < length; index++) {
      rest[index] = arguments[index + startIndex];
    }
    switch (startIndex) {
      case 0: return func.call(this, rest);
      case 1: return func.call(this, arguments[0], rest);
      case 2: return func.call(this, arguments[0], arguments[1], rest);
    }
    var args = Array(startIndex + 1);
    for (index = 0; index < startIndex; index++) {
      args[index] = arguments[index];
    }
    args[startIndex] = rest;
    return func.apply(this, args);
  };
}

var now = Date.now || function() {
  return new Date().getTime();
};

export function debounce(func, wait, immediate) {
  var timeout, previous, args, result, context;

  var later = function() {
    var passed = now() - previous;
    if (wait > passed) {
      timeout = setTimeout(later, wait - passed);
    } else {
      timeout = null;
      if (!immediate) result = func.apply(context, args);
      // This check is needed because `func` can recursively invoke `debounced`.
      if (!timeout) args = context = null;
    }
  };

  var debounced = restArguments(function(_args) {
    context = this;
    args = _args;
    previous = now();
    if (!timeout) {
      timeout = setTimeout(later, wait);
      if (immediate) result = func.apply(context, args);
    }
    return result;
  });

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

  return debounced;
}

export function throttle(func, wait, options) {
  var timeout, context, args, result;
  var previous = 0;
  if (!options) options = {};

  var later = function() {
    previous = options.leading === false ? 0 : now();
    timeout = null;
    result = func.apply(context, args);
    if (!timeout) context = args = null;
  };

  var throttled = function() {
    var _now = now();
    if (!previous && options.leading === false) previous = _now;
    var remaining = wait - (_now - previous);
    context = this;
    args = arguments;
    if (remaining <= 0 || remaining > wait) {
      if (timeout) {
        clearTimeout(timeout);
        timeout = null;
      }
      previous = _now;
      result = func.apply(context, args);
      if (!timeout) context = args = null;
    } else if (!timeout && options.trailing !== false) {
      timeout = setTimeout(later, remaining);
    }
    return result;
  };

  throttled.cancel = function() {
    clearTimeout(timeout);
    previous = 0;
    timeout = context = args = null;
  };

  return throttled;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 防抖(debounce):在指定的时间 n 秒后执行回调,如果在计算时间的过程中又被触发,则从新开始计算时间 fu...
    sharon_007阅读 880评论 0赞 0
  • 什么是防抖 函数防抖(debounce) 是指在一定时间内,在动作被连续频繁触发的情况下,动作只会被执行一次,也就...
    夕阳再美也会落幕阅读 354评论 0赞 1
  • https://hzu-zuoxiong.gitbooks.io/frontend_note/javascript...
    Time_Notes阅读 155评论 0赞 0
  • 一、认识防抖和节流函数 防抖和节流的概念其实最早并不是出现在软件工程中,防抖是出现在电子元件中,节流出现在流体流动...
    咸鱼不咸_123阅读 1,178评论 0赞 1
  • 原文链接[https://github.com/tofrankie/blog/issues/248] 一、前言 相...
    越前君阅读 1,163评论 0赞 15

友情链接更多精彩内容