前端工程师们都听过看起来很高级的词,节流和防抖,其实节流就是debounce,防抖就是throttle,其实这个也属于前端性能优化的一部分。在做远程搜索时,如果每输入1个字就调用1次接口,就会频繁查询数据库,假设我们的查询是"一二三四五",不考虑用户输入错误的情况,至少会请求5次。有没有一种方法,可以隔个几百毫秒再去查询呢?有没有更加高级的做法,用户输入完成后,停顿了几百毫秒再去查询呢?有没有一种方法,可以隔个几百毫秒再去查询呢?有,可以为函数设置一个setTimeout函数,相当于定时调用接口,这种方法是低效的,也是非常愚蠢的,需要控制开关定时器,一旦搜索功能多了,就更蠢了。有没有更加高级的做法,用户输入完成后,停顿了几百毫秒再去查询呢?有,debounce就是做这个事情的,lodash从0.1.0就支持了这个方法。css-tricks的lodash debounce demo<input type=“text” class=“autocomplete”>// 被debounce的函数,http请求,事件处理函数等等function make_ajax_request(){ // 这是一个调用后端api的方法}// 监听事件并且调用lodash的debounce方法$(’.autocomplete’).on(‘keydown’, _.debounce(make_ajax_request, 1300));});demo地址:https://codepen.io/dcorb/embe…vue项目中的lodash debounce demo<template> <input @input=“debounceHandleInput”/></template><script>import _ from ’lodash’;export default { name: ‘debounce’, data() { return { starTime: 0, endTime: 0, delay: 1000, }; }, computed: { debounceHandleInput() { return _.debounce(this.handleInput, this.delay); }, }, methods: { handleInput(e) { console.log(debounce wait时间为${this.delay}ms); console.log(‘触发了input事件’, e.target.value); this.startTime = new Date().getTime(); this.remoteMethod(); }, remoteMethod() { setTimeout(() => { const result = 后端请求已完成!; this.endTime = new Date().getTime(); const costTime = this.endTime - this.startTime; console.log(result); console.log(耗时${costTime}毫秒); }, 2000); }, },};</script>打印结果:debounce wait时间为1000ms触发了input事件 13131后端请求已完成!耗时2000毫秒在1000ms时间范围内触发,仅仅调用一次remoteMethod,也就是仅仅调用一次后端接口,达到我们的预期效果。debounce适用场景Debouncing a input event handler (this example explain this use case)Debouncing a resize event handlerDebouncing a save function in an autosave feature在做滚动加载时,如果用户滚动的幅度过大,会导致加载的内容过多,相当于水的流量没有控制,一瞬间大量的水量迸发而出,从而所看到的延后好几个与预期的下一个不符的情况当水流超过阀值时,最多释放出阀值量的水;水流小于阀值时,一切正常。有没有一种办法去控制水流的大小?有,throttle就是做这个事情的,lodash从0.1.0也支持了这个方法。具体demo就不写了,因为throttle常用于连续事件的事件处理函数。可以参考 https://css-tricks.com/the-di… 文章最后的demo,其中的throttle在scroll上的运用,就是throttle的正确打开方式。throttle适用场景Throttling a scroll event in infinite scroll(demo case)Throttling a mousemove/touchmove event handler in canvasdebounce和throttle的对比地址:http://demo.nimius.net/deboun…图片:通过在canvas上连续触发mousemove事件我们发现:debounce只有当连续事件停止后的一小段时间后再触发一次,连续事件结束后可能只触发一次throttle会在连续事件的过程中,每隔一段时间至少触发一次,连续事件结束后触发不止一次努力成为一个不掉队的前端工程师!