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

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

极简实现系列——手写防抖的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)
}

完事~


版权声明:本文为laishaojiang原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。