防抖和节流

31 阅读1分钟

防抖

function debounce(fn, delay = 200) {
            let timer = 0
            return function () {
                let context = this
                let args = [...arguments]
                if (timer) clearTimeout(timer)
                timer = setTimeout(() => {
                    fn.apply(context, args)
                }, delay);
            }
        }
// 非立即执行版本 在触发事件后函数 n 秒后才执行,而如果我在触发事件后的 n 秒内又触发了事件,则会重新计算函数执行时间。

function debounce(fn, delay = 200) {
            let timer = 0
            return function () {
                let context = this
                let args = [...arguments]
                if (timer) clearTimeout(timer)
                const callNow = !timer
                timer = setTimeout(() => {
                    timer = 0
                }, delay);
                if(callNow) fn.apply(context, args)
            }
        }
 // 立即执行版本,触发事件后函数会立即执行,然后 n 秒内不触发事件才能继续执行函数的效果。

节流

function throttle(fn, delay = 1000) {
            let timer = 0
            return function () {
                let context = this
                let args = arguments
                if(timer) return
                timer = setTimeout(() => {
                    fn.apply(context, args)
                    timer = 0
                }, delay);
            }
        }
// 非立即执行版,停止触发后会再执行一次

function throttle(fn, delay = 1000) {
            let pre = 0
            return function () {
                let now = Date.now()
                let context = this
                let args = arguments
                if(now - pre > delay){
                    fn.apply(context, args)
                    pre = now
                }
            }
        }
// 时间戳立即执行版本

function throttle(fn, delay = 1000) {
            let timer = 0, pre = 0
            return function () {
                let context = this
                let args = [...arguments]
                let now = Date.now()
                let remaining = delay - (now - pre)
                if(remaining <= 0 || remaining > delay){
                    if(timer) {
                        clearTimeout(timer)
                        timer = 0
                    }
                    pre = now
                    fn.apply(context, args)
                }else if(!timer){
                    timer = setTimeout(() => {
                        pre = Date.now()
                        timer = 0
                        fn.apply(context, args)
                    }, remaining);
                }
            }
        }
// 上面两种的结合,会在开始前和结束后都执行一次