Kasan Blog

节流

节流通俗解释:技能cd,最好写成通用的形式,因为不能为了一个功能写一个节流,那一百个功能难道要写100个节流?

应用场景:比如不想用户频繁点击按钮,想在规定时间内只允许点击一次

思路:

接收一个函数和时间,调用传入的fn函数,冷却中=true

设置一个计时器,时间设为传入的时间time,time过后,冷却中=false

// 节流就是「技能冷却中」
const throttle = (fn, time) => {
    let 冷却中 = false
    return (...args) => {
        if (冷却中) return
        fn.call(undefined, ...args)
        冷却中 = true
        setTimeout(() => {
            冷却中 = false
        }, time)
    }
}
// 还有一个版本是在冷却结束时调用 fn
// 简洁版,删掉冷却中变量,直接使用 timer 代替
const throttle = (fn, time) => {
    let timer = null
    return (...args) => {
        if (timer) { return }
        fn.call(undefined, ...args)
        timer = setTimeout(() => {
            timer = null
        }, time)
    }
}

const f = throttle(()=>{console.log('hi')}, 3000)

f() // 打印hi
f() // 技能冷却中

防抖

防抖通俗解释:点击B回城时,被打断,再点B回城,再被打断,再B….,直到回城成功。

一样写成通用的形式

应用场景:调整浏览器窗口大小时 只有规定时间后执行重新定位

思路:

接收fn 和 time

设置计时器,在time时间后执行fn,如果期间被打断

就重置计时器,重新开始计算time时间,time结束后执行fn

循环往复,直至fn被执行

// 防抖就是「回城被打断」
const 回城 = function(){
    console.log('回城成功')
}

const debounce = (fn, time) => {
    let timer = null
    return (...args) => {
        if (timer !== null) {
            clearTimeout(timer) // 打断回城
        }
        // 重新回城
        timer = setTimeout(() => {
            fn.call(undefined, ...args) // 回城后调用 fn
            timer = null
        }, time)
    }
}

const tp = debounce(回城,3000)

tp() //失败
tp() //失败
tp() //失败
tp() //三秒后成功