理解throttle debounce
比较
二者本质:都是限制频繁触发
二者区别:
throttle: 节流阀,保证多少ms内只执行一次。
debounce: 去抖,保证多少ms内不再被触发时就会执行一次。
类比电梯策略理解:
throttle:第一个人进来后15s运送一次,不等待。
debounde:第一个人进来15s后运送一次,假设15s内又有人进来,重新计时,一直到15s内不再有人进来则运送一次
一秒理解 throttle debounce:http://demo.nimius.net/debounce_throttle/
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.https://github.com/lishengzxc/bblog/issues/7
2.http://www.jianshu.com/p/fb08b7ef31de
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。