# 节流与防抖函数

本文部分来自于 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分钟

节流函数

概念

基础节流(无对象绑定)

对象绑定节流

带参数节流

对比

防抖函数

概念

基础防抖

对象绑定防抖

带参数防抖

对比