理解throttle debounce
比较
二者本质:都是限制频繁触发
二者区别:throttle: 节流阀,保证多少ms内只执行一次。debounce: 去抖,保证多少ms内不再被触发时就会执行一次。类比电梯策略理解:
throttle:第一个人进来后15s运送一次,不等待。
debounde:第一个人进来15s后运送一次,假设15s内又有人进来,重新计时,一直到15s内不再有人进来则运送一次一秒理解 throttle debounce:
throttle debounce 实现
以throttle-debounce 包代码解析:
debounce.js:var throttle = require('./throttle');module.exports = function ( delay, atBegin, callback ) { return callback === undefined ? throttle(delay, atBegin, false) : throttle(delay, callback, atBegin !== false);};
throttle.js:
module.exports = function ( 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;};
应用
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 事件进行查询;Reference
1.
2.