ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
### 简单了解 ***** * 防抖节流我相信大家都不陌生,简单理解,可有效的规避很多重复性(误)操作。 * 防抖:在规定时间内,操作时长间接性小于规定时间,只执行第一次或者最后一次;如:500ms执行一次,间接时间为100ms,一共操作时长2000ms,则会执行**1**次。 * 节流:规定时间内执行一次,操作时长大于规定时间,则开启下一个执行;如:500ms执行一次,一共操作时长2000ms,则会执行**4**次。 ### 问题所在 ***** 问题:`clearTimeout(timeout)`后,`timeout=???`、以及定时器有什么变化? 先简单过一下 下面的代码,平淡无奇哈,但是关键在于这句 `timeout && clearTimeout(timeout)`,试想经过`clearTimeout(timeout)`后,`timeout=???`,等于`null`吗?可以看到清除定时器后timeout的值并非null,而且还不变,这是不是有点匪夷所思啊? * 接下来我们分析一下,我们开启一个定时器,并且把这个定时器记录赋给一个变量,这时候定时器在内存中,可以通过该变量对应id去查找到,经过`clearTimeout(timeout)`后,只是对内存中的定时器进行清除,仅此而已,并未对变量进行修改操作; * 如果我们直接进行`timeout=null`,而没有`clearTimeout(timeout)`,那么定时器是没有清除的,只是把timeout指向变了,并没有清除掉定时器,此时定时器在内存中虽然没有变量指向它,但它仍存在内存中,待wait时间一到,就执行callback函数。 ![](https://img.kancloud.cn/18/48/18482e9ae34e5e10670195f00d26c19f_630x259.png) ### 防抖函数实现 ``` /**  * 防抖函数:多次触发事件,事件处理函数只执行一次,并且在触发操作后执行。  * 原理:利用闭包原理,就是函数需要在刚完成时需要被使用,赋值给一个变量,由这个变量去使用。  * @param {*} callback 回调函数  * @param {*} wait 延迟时间,默认500ms  * @param {*} immediate 是否立即执行,默认是  */ export const debounce = (callback, wait = 500, immediate = true) => {   let timeout = null;   let debounced = function() {     let self = this;     timeout && clearTimeout(timeout);     if (immediate) {       let callNow = !timeout;       if (callNow) callback.apply(self, arguments);       timeout = setTimeout(() => {         timeout = null;       }, wait);     } else {       timeout = setTimeout(() => {         callback.apply(self, arguments);       }, wait);     }   };   debounced.cancel = function() { clearTimeout(timeout);     timeout = null;   };   return debounced; }; ``` ### 节流函数实现 顺便附上节流函数 ``` /**  * 节流函数:触发操作后,在间隔连续时间内只执行一次,过了规定间隔时间后,才进行下一次调用  * 原理:对函数进行间隔操作,在规定间隔时间内,如有重复操作,则清除掉本次操作  * @param {*} callback  * @param {*} wait 间隔时间,默认500ms  * @param {*} options = { leading: false, // 禁用第一次执行 trailing: false // 禁用停止触发的回调 }  * @returns  */ export const throttle = (callback, wait = 500, options = {}) => {   let time, context, args;   let previous = 0;   let later = function() {     previous = options.leading === false ? 0 : new Date().getTime();     time = null;     callback.apply(context, args);     if (!time) context = args = null;   };   let throttled = function() {     let now = new Date().getTime();     if (!previous && options.leading === false) previous = now;     let remaining = wait - (now - previous);     context = this;     args = arguments;     if (remaining <= 0 || remaining > wait) {       if (time) {         clearTimeout(time);         time = null;       }       previous = now;       callback.apply(context, args);       if (!time) context = args = null;     } else if (!time && options.trailing !== false) {       time = setTimeout(later, remaining);     }   };   throttled.cancel = function() {     clearTimeout(time);     time = null;     previous = 0;   };   return throttled; }; ```