极简实现系列——手写节流throttle函数

    技术2022-07-11  88

    极简实现系列 是用最简单的代码实现一些常见的方法,目的是为了帮助理解原理,所以并没有考虑太多限制条件

    极简实现系列——手写防抖的debounce函数

    极简实现系列——手写bind

    极简实现系列——超低配版Promise

    极简实现系列——手写call和apply

    极简实现系列——手写eventBus

    极简实现系列——手写new


    节流函数在日常中还是经常用到的,比如在页面滚动的时候调用函数,要是不做节流的话,就会一直调用,造成性能浪费。实现的原理也非常简单,一般有两种方式,我们先来说下第一种:

    一:利用定时器

    原理:定义一个开关变量flag,调用的时候把它赋值为true,然后再写一个定时器,待定时器结束后再赋值为false。 再定时器还未结束期间,再次调用函数时判定flag,为true的话直接return就行

    知道原理后我们先随便写一个极简版

    let timer = null let flag = false function throttle(fn, delay){ if(flag) return // true 表示上次执行未结束 flag = true timer = setTimeout(() => { fn() flag = false // 结束后重新设置为false }, delay) } // 测试函数 function test() { console.log('test') } window.onscroll = function(e) { // test() // 不用节流的话,页面滚动一直在调用 throttle(test, 1000) // 加上节流,即使页面一直滚动,也只会每隔一秒执行一次test函数 }

    完事了~

    当然这些是比较粗暴的,功能也有一些限制,比如我希望test函数可以传参数。我们再来优化一下

    优化版

    function throttle(fn, delay){ let timer = null // 把变量放函数里面,避免全局污染 let flag = false let that = this return function() { if(flag) return flag = true let arg = arguments // 此处为fn函数的参数 timer = setTimeout(() => { fn.apply(that, arg) flag = false }, delay) } } function test(a,b) { console.log(a,b) } let throttleTest = throttle(test, 1000) window.onscroll = function(e) { throttleTest(1,2) }

    二:利用时间戳

    原理:获取调用函数时的时间戳,计算前后两次调用的时间戳之差,如果大于设定的时间则继续,否则return

    很简单,直接看代码吧

     

    function throttle(fn, delay){ let that = this let lastTime = 0 return function() { let nowTime = new Date().getTime() if(nowTime - lastTime < delay) return // 两次时间间隔比设定的delay则return let arg = arguments // 此处为fn函数的参数 fn.apply(that, arg) lastTime = nowTime // 把当前时间赋值给lastTime } } function test(a,b) { console.log(a,b) } let throttleTest = throttle(test, 1000, true) window.onscroll = function(e) { throttleTest(1,2) }

    完事~

    Processed: 0.009, SQL: 9