原生js实现防抖函数,为什么这么写无法实现防抖效果

发布于 2022-09-12 22:44:53 字数 918 浏览 14 评论 0

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)
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

╰◇生如夏花灿烂 2022-09-19 22:44:53

因为你写的timerCreateWebSocket是在函数内的,每次刷新都重新定义为undefined,而下方使用闭包,timeout变量的状态能保存。

独自唱情﹋歌 2022-09-19 22:44:53

按理说你的写法是可以实现防抖的,所以你可能误解了防抖效果,你的 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 执行返回的函数作为回调函数——重点是要维持一个每次执行点击回调时访问都一致的定时器句柄timerCreateWebSockettimeout

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文