# 节流与防抖函数
本文部分来自于 https://github.com/TabooLib/taboolib (opens new window) 源代码注释
# 节流函数
# 概念
节流函数(Throttle Function) 用于限制函数在指定时间间隔内的执行频率,避免函数在短时间内重复触发
# 基础节流(无对象绑定)
创建与特定对象无关的节流操作,在指定时间窗口内仅执行一次操作
# 方法签名
throttle(delay: Long, action: () -> Unit)
# 示例
// 创建一个 500ms 的节流函数
val throttledAction = throttle(500) {
println("节流后输出")
}
// 高频使用场景
throttledAction() // 执行
throttledAction() // 不会执行
throttledAction() // 不会执行
// 等待 600 毫秒后
Thread.sleep(600)
throttledAction() // 重新激活
// 最终输出:
// 节流后输出
// 节流后输出
# 对象绑定节流
针对特定类型对象(如 Player)的节流操作,不同对象独立计算时间窗口
# 方法签名
throttle<K : Any>(delay: Long, noinline action: (K) -> Unit)
# 示例
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)
# 示例
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)
# 示例
val debouncedAction = debounce(500) {
println("防抖后输出")
}
// 连续调用
debouncedAction()
debouncedAction() // 重置计时
debouncedAction() // 取消前两次,延迟 500ms 后执行
// 等待 600ms
Thread.sleep(600)
// 最终输出:
// 防抖后输出
# 对象绑定防抖
针对特定对象(如玩家)使用。在指定时间内只执行一次函数,如果在这段时间内再次调用函数,则重新计时
# 方法签名
debounce<K: Any>(delay: Long, async: Boolean, action: (K) -> Unit)
# 示例
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)
# 示例
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
# 对比
| 特性 | 基础 | 对象绑定 | 带参数 |
|---|---|---|---|
| 对象关联 | ❌ | ✅ | ✅ |
| 参数传递 | ❌ | ❌ | ✅ |
| 计时策略 | 全局重置 | 按对象重置 | 按对象重置 |
进阶
8分钟