美文网首页
关于防抖和节流

关于防抖和节流

作者: 白手_ | 来源:发表于2021-03-16 00:23 被阅读0次

    防抖(debounce)


    描述:如果短时间内大量触发同一事件,希望在事件连续触发的过程中并不执行其回调函数,而是等到最后一次触发后,等待一小会再执行回调

    任务:

    1. 第一次触发时,尝试在一小会后执行 (举个🌰:老王去做贼,先到你家门口观察一小会,伺机行动)
    2. 后续连续的触发需要抑制回调的执行 (老王:有人路过,取消行动,等5分钟看看情况....终于,没人路过了,开干!)
    function debounce(fn, delay) {
        let timer = null
        return function() {
            if(timer) {
                clearTimeout(timer) // 连续触发时,取消第一次触发时建立的setTimeout
            }
            timer = setTimeout(() => {
                fn()
            }, delay)
        }
    }
    

    上面的代码有个问题:fn不支持传递参数,我们来改写一下

    function debounce(fn, delay) {
        let _self = fn
        let timer = null
        return function() {
            let args = arguments // 类似select@change,回调函数是有参数的
            let _me = this
            if(timer) {
                clearTimeout(timer) // 连续触发时,取消第一次触发时建立的setTimeout
            }
            timer = setTimeout(() => {
                _self.apply(_me, args)
            }, delay)
        }
    }
    

    节流(throttle)


    描述:同样是短时间大量触发同一事件的场景下,我们希望回调函数有节制地执行,比如200ms执行一次

    场景:

    1. 在具有search功能的input中执行doSearch查询,用户的输入是连续的,如果不做限制,每输入一个字符则执行一次查询
    2. 比如在画板中监听鼠标移动(mousemove),并在位置信息文本中更新对应的位置,mousemove事件的执行频率非常快(scroll,resize也是类似的),则更新dom的频率是极高的,然而用户其实并不需要如此高的通知频率,一秒钟更新2,3次即可 (画板的例子有个特殊需求,最后一次也必须执行,可以思考下)

    举个不成熟的🌰:你(亚索)和小明(石头人)玩LOL

    1. 快R对面中单
    2. 好嘞,我刚学大招(第一次),Boom....suo li a ka tong,漂亮
    3. R它
    4. Boom....suo li a ka tong,你开始有点上头 (假设第一次放大招没有冷却)
    5. R它...R它...R它
    6. 老大,我的技能在冷却啊,等好了再来
    7. R它...R它...R它
    8. 你别催了,技能好了就来

    任务:

    1. 首次执行时,跳过限制,直接执行
    2. 首次执行过后及后续每次执行后的一段时间(delay)内,不执行
    function throttle(fn, interval) {
        let isFirstTime = true
        let timer = null
        return function() {
            let args = arguments
            let _me = this
            if(isFirstTime) {
                _self.apply(_me, args)
                isFirstTime = false
                return false
            }
            if(timer) {
                return false
            }
            timer = setTimeout(() => {
                clearTimeout(timer) // 注意为什么写在_self.apply()前面,函数的执行需要时间,时效性考虑
                timer = null
                _self.apply(_me, args)
            }, interval || 200)
        }
    }
    

    相关文章

      网友评论

          本文标题:关于防抖和节流

          本文链接:https://www.haomeiwen.com/subject/lehrcltx.html