手写节流(throttle)防抖(debounce)函数

141 阅读1分钟

1. 节流

定义:在规定时间内,如果动作(事件)连续触发,节流后只触发一次。

// 定时器实现
function throttle(fn, delay = 100) {

    let timer = null // 1

    return function () {
        if (timer) {
            return
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments) // 2
            timer = null
        }, delay)
    }
}

// 时间戳实现
function debounce(fn, delay = 500) {

    let activeTime = 0

    return function () {
    
        let currentTime = Date.now()
        if (currentTime - activeTime > delay) {
            fn.apply(this, arguments)
            activeTime = currentTime
        }
    }
}

myDiv.addEventListener('drag', throttle(function (e) {
    console.log(e.offsetX, e.offsetY)
}))

2. 防抖

定义:在规定时间内,如果动作(事件)持续触发,则只触发规定时间后的最后一次动作。

function debounce(fn, delay = 500) {

    let timer = null // 1

    return function () {
        if (timer) {
            clearTimeout(timer)
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments) // 2
            timer = null
        }, delay)
    }
}

myInput.addEventListener('change', debounce(function (e) { // 3
    console.log(myInput.value)
}, 600))

myInput.addEventListener('change', function(event) {
    // 这里用来对比不使用防抖
})

需要注意的点

1.节流防抖中timer为闭包,会一直存在。

2.直接执行fn()可以吗?答案是可以的,也可以起到节流防抖的作用,但是会丢失参数和this。

3.调用debounce/throttle时候使用箭头函数,this会指向window。