debounce(handleCreateWebSocket,2*1000)()
每次触发这个点击事件,无法实现防抖效果,点击多少次,执行了多少次,为什么?
var btnCreateWebSocket = document.querySelector('.btn-create-webSocket-container')
if (btnCreateWebSocket) {
btnCreateWebSocket.onclick = function () {
console.log('btnCreateWebSocket')
// if(!chatGlobalData['connect']) {
clearTimeout(timerCreateWebSocket)
timerCreateWebSocket = setTimeout(function(){
createWebSocket()
}, 2*1000)
// }
}
}
防抖函数实现
function debounce (func, wait){
var timeout;
return function(){
var self = this; // 因为apply会改变this的指向性
clearTimeout(timeout)
timeout = setTimeout(function(){
// setTimeout 属于 window 对象
// 直接使用func.apply(this) 会在add函数里面改变this为window,
// 这里也可以用ES6的箭头函数
func.apply(self)
}, wait)
}
}
###因为你写的timerCreateWebSocket是在函数内的,每次刷新都重新定义为undefined,而下方使用闭包,timeout
变量的状态能保存。
按理说你的写法是可以实现防抖的,所以你可能误解了防抖效果,你的 console.log
应该放在 createWebSocket()
上一行,这样就能确保你看到的打印效果是防抖之后的效果。
但是这样的写法并不地道,因为意外创建了一个全局变量 timerCreateWebSocket
,相关知识在这里不赘述,总之是不推荐的写法。
这样应该可行:
btnCreateWebSocket.onclick = (function() {
var timerCreateWebSocket;
return function () {
console.log('btnCreateWebSocket')
// if(!chatGlobalData['connect']) {
clearTimeout(timerCreateWebSocket)
timerCreateWebSocket = setTimeout(function(){
createWebSocket()
}, 2*1000)
// }
}
})();
使用 debounce
的时候是将 debounce
执行返回的函数作为回调函数,而这种写法是将 IIFE
执行返回的函数作为回调函数——重点是要维持一个每次执行点击回调时访问都一致的定时器句柄 即 timerCreateWebSocket
或 timeout
。