IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> js防抖节流函数的实现与优化 -> 正文阅读

[JavaScript知识库]js防抖节流函数的实现与优化

预备知识

剩余参数、默认参数、定时器、箭头函数this指向、apply函数、Date对象…

防抖

持续触发事件,n秒内再次触发某事件,将重新计算时间才执行。因此,只有最后一次操作能被触发

function debounce(fn, delay = 500) {
    let timer = null

    return (...args) => {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, args)
        }, delay)
    }
}

节流

持续触发事件,n秒内再次触发某事件,将等待上一次事件处理函数完成后,才执行。可以把这个理解成游戏中的“技能冷却时间”。

思想碰撞

定时器实现

function throttle(fn, delay = 1500) {
    let timer = null

    return (...args) => {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, args)
            timer = null
        }, delay)
    }
}

存在的问题

第一次触发时,也将等待delay时间才能执行。与冷却时间的初衷不符合!

定时器优化(个人觉得最佳方法,文尾有解释)

使用first记录是否是第一次触发函数。如果是第一次触发,立即执行。如果不是,则将采用定时器。

function throttle(fn, delay = 1500) {
    let timer = null
    let first = true

    return (...args) => {
        if (timer) {
            return
        }
        if (first) {
            fn.apply(this.args)
            first = false
            return
        }

        timer = setTimeout(() => {
            fn.apply(this, args)
            timer = null
        }, delay)
    }
}
优化后解决的问题

若第一次触发,将立即执行,不会有任何延迟。

时间戳实现

function throttle(fn, delay = 1500) {
    let pre = +new Date()

    return (...args) => {
        const now = +new Date()
        if ((now - pre) >= delay) {
            fn.apply(this, args)
            pre = +new Date()
        }
    }
}

存在的问题

  1. 第一次触发时,也将等待delay时间才能执行。同样与冷却时间的初衷不符合!
  2. 最后一次触发时,若now - pre < delay将不会执行。
  3. 使用Date对象获取时间戳,计算时间差的办法,会有一个安全漏洞—更改本地时间会出错,因此不推荐!

时间戳实现优化(时间戳+定时器)

function throttle(fn, delay = 1500) {
    let timer = null // 定时器
    let pre = +new Date() // 计算开始时间

    return (...args) => {
        const now = +new Date() // 计算当前时间
        const remaining = now - pre // 计算剩余时间
        clearTimeout(timer) // 取消先前调用的setTimeout
        if(remaining > delay) {
            // 超过冷却时间,立即执行
            fn.apply(this, args)
            pre = +new Date() // 更新开始时间
        }else {
            // 未超过冷却时间,禁止执行。同时保证最后一次调用,仍然可以执行。
            timer = setTimeout(() => {
                fn.apply(this, args)
            }, delay)
        }
    }
}
优化后解决的问题

最后一次触发,若now - pre < delay也将会执行。

优化后仍然存在的问题
  1. 第一次触发,会有延迟,依旧需要等待delay时间差才能执行。
  2. 修改本地时间,任会出现错误。

总结

个人觉得使用定时器优化方案是最佳方案。优点如下:

  1. 第一次执行将立即执行,不会有任何延迟。
  2. 最后一次执行,也将会触发执行。
  3. 不存在更改本地时间的BUG。

网友们觉得呢?欢迎评论区讨论~

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-30 18:14:48  更:2022-03-30 18:16:49 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 4:26:19-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码