吐槽:防抖节流这两个名字起的很不好,一点都不形象
英雄联盟玩过吧?王者荣耀玩过吧?
那开始吧:
节流「技能冷却中」
闪现用过吧?
我点击闪现后,是不是会进入一段 CD?
CD 期间再点击闪现,是不是没有反应?
那用代码实现这个功能吧:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const sx = () => { console.log('闪现') }
let 冷却中 = false let timer = null
function onClickSx() { if (冷却中) { return } sx() 冷却中 = true timer = setTimeout(() => { 冷却中 = false }, 120 * 1000) }
|
这,就是节流
那如何写出符合任何需求的节流呢?
写一个函数,实现任何技能都可以进入冷却
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| const sx = distance => { console.log('闪现') }
const throttle = (skill, time) => { let timer = null return (...args) => { if (timer) { return } skill.call(undefined, ...args) timer = setTimeout(() => { timer = null }, time) } }
const sx2 = throttle(sx, 120 * 1000)
|
再修修改改,变成了标准写法的节流
标准写法:
1 2 3 4 5 6 7 8 9 10 11 12
| const throttle = (fn, time) => { let timer = null return (...args) => { if (timer) { return } fn.call(undefined, ...args) timer = setTimeout(() => { timer = null }, time) } }
|
防抖「回城被打断」
我点击回城,但是被小兵攻击了,所以我回城被打断,需要重新回城
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const f = () => { console.log('回城成功') }
let timer = null
function x() { if (timer) { clearTimeout(timer) } timer = setTimeout(() => { fn() timer = null }, 3000) }
|
那写一个满足防抖需求的:写一个通用的函数,任何功能都可以实现打断了之后再重新计时
标准写法:
1 2 3 4 5 6 7 8 9 10 11 12
| const debounce = (fn, time) => { let timer = null return (...args) => { if (timer != null) { clearTimeout(timer) } timer = setTimeout(() => { fn.call(undefined, ...args) timer = null }, time) } }
|
使用场景
节流
我不希望用户频繁点击按钮的时候使用
防抖
当用户进行一个频繁拖动操作的时候,我希望在拖动停止之后再去实现一个效果
感谢阅读,下次见 :)