极简实现系列 是用最简单的代码实现一些常见的方法,目的是为了帮助理解原理,所以并没有考虑太多限制条件
节流函数在日常中还是经常用到的,比如在页面滚动的时候调用函数,要是不做节流的话,就会一直调用,造成性能浪费。实现的原理也非常简单,一般有两种方式,我们先来说下第一种:
一:利用定时器
原理:定义一个开关变量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版权协议,转载请附上原文出处链接和本声明。