Debouncing
防抖是一种技术,它延迟执行一个操作,直到自上次调用以来经过一段指定的时间。每次新的调用都会重置计时器。这对于像输入时搜索这样的场景很有用,在这种情况下,您希望等到用户停止输入后再执行搜索查询。
显示代码
- Java
基本用法
Debouncer 类提供了一种简单的方式来防抖操作。创建一个带有延迟(以秒为单位)的 Debouncer,然后调用 run(),传入您想要防抖的操作:
Debouncer debounce = new Debouncer(0.3f);
textField.onModify(e -> {
debounce.run(() -> search(textField.getText()));
});
在这个例子中,search() 方法仅在用户停止输入 300 毫秒后被调用。每次击键都会通过 onModify 事件重置计时器,因此快速输入不会触发多个搜索。
工作原理
当您用一个操作调用 run() 时:
- 如果没有待处理的操作,
Debouncer会在延迟后计划该操作运行 - 如果已经有一个操作在等待,之前的操作会被取消,计时器会用新的操作重新启动
- 一旦延迟结束而没有其他调用,操作就会执行
Debouncer 在 UI 线程上运行,使用 webforJ 的 Interval 机制,因此您不需要在 Environment.runLater() 中包裹 UI 更新。
延迟单位
延迟参数使用秒作为单位,而不是毫秒。使用 0.3f 代表 300 毫秒,或使用 1.5f 代表 1.5 秒。
控制执行
以下方法可用于更精确地处理 Debouncer 的执行和使用:
取消待处理操作
使用 cancel() 停止待处理操作的执行:
Debouncer debounce = new Debouncer(1f);
debounce.run(() -> saveDocument());
// 用户在保存执行前导航离开
debounce.cancel();
取消待处理的防抖
像时间间隔一样,在组件被销毁时取消待处理的防抖操作是个好习惯。这可以防止内存泄漏,避免在已销毁的组件上执行操作时发生错误:
public class SearchPanel extends Composite<Div> {
private final Debouncer debounce = new Debouncer(0.3f);
@Override
protected void onDidDestroy() {
debounce.cancel();
}
}
强制立即 执行
使用 flush() 立即执行待处理的操作:
Debouncer debounce = new Debouncer(0.5f);
textField.onModify(e -> {
debounce.run(() -> validateInput(textField.getText()));
});
// 在表单提交前强制验证
submitButton.onClick(e -> {
debounce.flush();
if (isValid()) {
submitForm();
}
});
检查待处理状态
使用 isPending() 验证操作是否在等待执行:
Debouncer debounce = new Debouncer(0.3f);
if (debounce.isPending()) {
statusLabel.setText("正在处理...");
}
事件级防抖与 Debouncer
webforJ 提供了两种防抖的方法:
| 特性 | Debouncer | ElementEventOptions.setDebounce() |
|---|---|---|
| 范围 | 任何操作 | 元素事件仅 |
| 位置 | 服务器端 | 客户端 |
| 单位 | 秒(浮点数) | 毫秒(整数) |
| 灵活性 | 完全控制,具有取消/强制功能 | 自动与事件绑定 |
当您需要对防抖进行编程控制,例如取消或刷新待处理操作时,使用 Debouncer。当您希望对元素事件进行简单的客户端防抖而不需要额外的服务器往返时,使用 ElementEventOptions。
// 使用 ElementEventOptions 进行客户端防抖
ElementEventOptions options = new ElementEventOptions();
options.setDebounce(300);
element.addEventListener("input", e -> {
// 这个处理程序在客户端进行了防抖
}, options);