Skip to content

节流与防抖函数

本文部分来自于 https://github.com/TabooLib/taboolib 源代码注释

节流函数

概念

节流函数(Throttle Function) 用于限制函数在指定时间间隔内的执行频率,避免函数在短时间内重复触发

基础节流(无对象绑定)

创建与特定对象无关的节流操作,在指定时间窗口内仅执行一次操作

方法签名

throttle(delay: Long, action: () -> Unit)

示例

kotlin
// 创建一个 500ms 的节流函数
val throttledAction = throttle(500) {
    println("节流后输出")
}

// 高频使用场景
throttledAction() // 执行
throttledAction() // 不会执行
throttledAction() // 不会执行

// 等待 600 毫秒后
Thread.sleep(600)
throttledAction() // 重新激活

// 最终输出:
// 节流后输出
// 节流后输出

对象绑定节流

针对特定类型对象(如 Player)的节流操作,不同对象独立计算时间窗口

方法签名

throttle<K : Any>(delay: Long, noinline action: (K) -> Unit)

示例

kotlin
val playerThrottle = throttle<Player>(500) { player ->
    println("${player.name} 触发操作")
}

// 高频使用场景
playerThrottle(player) // 执行
playerThrottle(player) // 不会执行
playerThrottle(player) // 不会执行

// 等待 600 毫秒后
Thread.sleep(600)
playerThrottle(player) // 重新激活

// 最终输出:
// player 触发操作
// player 触发操作

带参数节流

支持传递额外参数的节流实现,保留首次调用参数,忽略后续参数

方法签名

throttle<K: Any, T>(delay: Long, action: (K, T) -> Unit)

示例

kotlin
val messageThrottle = throttle<Player, String>(500) { player, msg ->
    println("${player.name}: $msg")
}

// 高频使用场景
messageThrottle(player, "我是坏黑") // 执行
messageThrottle(player, "我是奶龙") // 不会执行
messageThrottle(player, "我是Bkm016") // 不会执行

// 等待 600 毫秒后
Thread.sleep(600)
messageThrottle(player, "我是神秘人") // 重新激活

// 最终输出:
// player: 我是坏黑
// player: 我是神秘人

对比

特性基础对象绑定带参数
对象关联
参数传递
独立时间窗口全局按对象按对象
适用场景全局状态操作玩家行为限制带参数的行为限制

防抖函数

概念

防抖函数(Debounce Function) 用于延迟函数执行直到特定时间段内没有新触发,适用于处理高频事件中只需响应最后一次操作的场景

基础防抖

创建全局防抖操作,在最后一次调用后等待指定延迟执行动作,期间新调用会重置计时器

方法签名

debounce(delay: Long, async: Boolean, action: () -> Unit)

示例

kotlin
val debouncedAction = debounce(500) {
    println("防抖后输出")
}

// 连续调用
debouncedAction()
debouncedAction() // 重置计时
debouncedAction() // 取消前两次,延迟 500ms 后执行

// 等待 600ms
Thread.sleep(600)

// 最终输出:
// 防抖后输出

对象绑定防抖

针对特定对象(如玩家)使用。在指定时间内只执行一次函数,如果在这段时间内再次调用函数,则重新计时

方法签名

debounce<K: Any>(delay: Long, async: Boolean, action: (K) -> Unit)

示例

kotlin
val debouncedAction = debounce<Player>(500) { player ->
    println("玩家 ${player.name} 的防抖后输出")
}

// 连续调用
debouncedAction(player)
debouncedAction(player) // 重置计时
debouncedAction(player) // 取消前两次,延迟 500ms 后执行

// 等待 600 毫秒
Thread.sleep(600)

// 最终输出:
// 玩家 player 的防抖后输出

带参数防抖

支持传递额外参数的防抖实现,保留首次调用参数,忽略后续参数

方法签名

debounce<K: Any, T>(delay: Long, async: Boolean, action: (K, T) -> Unit)

示例

kotlin
val debouncedAction = debounce<Player, String>(500) { player, message ->
    println("玩家 ${player. name} 的防抖后输出:$message") 
}  

// 连续调用
debouncedAction(player, "消息1")
debouncedAction(player, "消息2") // 重置计时
debouncedAction(player, "消息3") // 取消前两次,延迟 500ms 后执行

// 等待 600 毫秒
Thread. sleep(600)  

// 最终输出:
// 玩家 player 的防抖后输出:消息3

对比

特性基础对象绑定带参数
对象关联
参数传递
计时策略全局重置按对象重置按对象重置