原生js中

简单实现:

function a() {
console.log('触发了!!!')
}
// 节流: 规定的时间内,只能触发一次;
// 一般用于:点击抢票、秒杀按钮
function throttle(fn, delay) {
let firstTime = Date.now()
return function () {
let lastTime = Date.now()
let args = [...arguments]
if(lastTime-firstTime >= delay) {
fn(...args)
firstTime = Date.now()
}
}
}

// 防抖:在规定的时间内,触发多个的话,会清除每一次的定时器,直到在规定的时间内没有触发
// 函数才会执行!一般用于用户滚动、浏览器窗口大小变化。
function debounce(fn, time) {
let timer = null;
return function () {
clearInterval(timer)
let args = [...arguments]
timer = setTimeout(() => {
fn(...args)
}, time)
}
}
addEventListener('resize', debounce(a, 1000))

 

防抖 - debounce

<template>
<div @mousemove="move">
{{text}}
</div>
</template>
<script>
export default {
data() {
return {timer: null}
},
methods: {
move() {
this.debounce(this.run, 1000)
},
run() {
this.text ++
},
debounce(fn, timing) {
clearTimeout(this.timer)
console.log(this.timer)
this.timer = setTimeout(fn, timing)
}
}
}
</script>

第一次执行debounce函数的时候,timer为null,执行clearTimeout(this.timer)时,可以忽略,接着看到setTimeout,会把回调函数放到事件队列中去,1秒钟之后会执行,并且产生一个唯一标识 timer。

接着如果在这1秒钟之内,又执行了debounce函数,也就是第二次执行:

看到clearTimeout(this.timer),它会把上一次的timer标识清除掉(也就是把上一次在事件队列中的函数清除),然后在接着执行setTimeout,还是会把回调函数放到事件队列中去,等待1秒钟之后执行,并且再次产生一个唯一标识 timer,依次类推··· ···

如果,在规定的时间内debounce函数只触发了一次,那么就正常执行。

下边是没加 clearTimeout(this.timer) 效果:

防抖、节流_回调函数

 加了clearTimeout(this.timer) 的效果:

防抖、节流_唯一标识_02