Throttle Debounce 总结

比较

二者本质:都是限制频繁触发

二者区别:

  • throttle: 节流阀,保证多少ms内只执行一次。
  • debounce: 去抖,保证多少ms内不再被触发时就会执行一次。

类比电梯策略理解:

throttle:第一个人进来后15s运送一次,不等待。
debounde:第一个人进来15s后运送一次,假设15s内又有人进来,重新计时,一直到15s内不再有人进来则运送一次

一秒理解 throttle debounce:http://demo.nimius.net/debounce_throttle/

throttle debounce 实现

export function throttle(delay, noTrailing, callback, debounceMode) {
  var timeoutID;
  // Keep track of the last time `callback` was executed.
  var lastExec = 0;
  if (typeof noTrailing !== 'boolean') {
    debounceMode = callback;
    callback = noTrailing;
    noTrailing = undefined;
  }
  function wrapper() {
    var self = this;
    var elapsed = Number(new Date()) - lastExec;
    var args = arguments;
    // Execute `callback` and update the `lastExec` timestamp.
    function exec() {
      lastExec = Number(new Date());
      callback.apply(self, args);
    }
    function clear() {
      timeoutID = undefined;
    }
    if (debounceMode && !timeoutID) {
      exec();
    }
    if (timeoutID) {
      clearTimeout(timeoutID);
    }
    if (debounceMode === undefined && elapsed > delay) {
      // throttle时,根据时间戳之差是否大于delay决定是否执行回调
      exec();
    } else if (noTrailing !== true) {
      // debounce时,setTimeout延迟执行回调
      timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
    }
  }

  return wrapper;
}

export function debounce(delay, atBegin, callback) {
  return callback === undefined ? throttle(delay, atBegin, false) : throttle(delay, callback, atBegin !== false);
}

应用

shop.js: // 输入关键字查询门店

import { throttle, debounce } from 'throttle-debounce';
...
debounce(200, async(val) => { await this.getShopList(val); });
...

还可以参考underscore, lodash 中throttle, debounce的实现,做了更多的兼容和考虑。

throttle debounce 应用场景

throttle:
监听resize事件做一些DOM元素的定位更改;
监听scroll 事件判断上拉时是否要加载数据
debounce:
搜索框输入发送ajax请求,监听onchange or keyup 事件进行查询;

参考

posted @ 2021-05-21 17:36  Jone_chen  阅读(426)  评论(0编辑  收藏  举报