5

我想我在这里描述的东西可能有一个名字,但我不知道。所以我的第一个问题是知道这种技术的名称。

这是一个示例:假设您正在网页上实现实时搜索。每次用户在搜索框中键入内容时,您都会触发一个新的搜索查询,并且结果会尽可能频繁地更新。这是一件愚蠢的事情,因为您将发送比您实际需要的更多的查询。每 2-3 个字母发送一次请求或最多每 100 毫秒发送一次请求可能就足够了。

因此,一种技术是安排在键入键后立即执行查询,如果仍有计划但未执行的查询,请取消它们,因为它们现在已经过时了。


现在更具体地说,是否有特定的模式或库可以在 Java 中解决这个问题?

我必须在一个 Swing 应用程序中解决这个问题,我使用了一个 ExecutorService,它返回了可以取消的 ScheduledFutures。问题是我必须为我想要“缓冲”的每个方法调用手动创建一个 Runnable,并跟踪每个 Future 以取消它。

我确定我不是第一个实现这样的东西的人,所以一定有一个可重用的解决方案吗?可能在 Spring 中带有注释和代理?

4

3 回答 3

12

Given the other answers, and after some searching, it seems there's indeed no library that does what I wanted.

I created one and put it on GitHub. Future readers of this question may find it interesting.

https://github.com/ThomasGirard/JDebounce

I don't think it's very good yet but at least it works and can be used declaratively:

@Debounce(delayMilliseconds = 100)
public void debouncedMethod(int callID, DebounceTest callback) { }
于 2013-09-12T07:45:42.927 回答
1

您需要的称为debounceing。您应该检查jQuery Throttle/Debounce 插件(顺便说一句,它完全独立于 jQuery,除了使用相同的命名空间)。debounce 部分涵盖了您需要的内容:

使用 jQuery throttle / debounce,你可以传递一个延迟和函数来 $.debounce获得一个新函数,当重复调用时,每个“一堆”调用只执行一次原始函数,有效地将多个顺序调用合并到一个执行中开始或结束。

Underscore.js有同样的方法:

_.debounce(function, wait, [immediate]) 

创建并返回传递函数的新去抖动版本,该版本将推迟其执行,直到wait自上次调用以来经过毫秒。对于实现仅在输入停止到达后才应发生的行为很有用。例如:渲染 Markdown 注释的预览,在窗口停止调整大小后重新计算布局等等。

// example: debounce layout calculation on window resize
var lazyLayout = _.debounce(calculateLayout, 300);
$(window).resize(lazyLayout);

[编辑]

我错误地阅读了“Javascript”而不是 Java。实际的 Java 解决方案是由 OP之后编写的。

于 2013-09-11T08:49:15.417 回答
1

如果不使用一些额外的基础设施,就像你对 executor 和 futures 所做的那样,这在 Java 中是无法解决的。在 Java 中以语法简洁的方式解决这个问题是不可能的。

您将始终需要某种方法结果包装器,因为该机制会立即返回,但稍后会检索实际结果。在您的情况下,这是通过 Future 完成的。

您将始终需要能够以允许延迟执行的方式指定要执行的代码。在大多数语言中,这是使用函数指针或函数值或闭包来完成的。在 Java 中,缺少这些语言特性,这通常是通过传递一个对象来实现的,该对象实现了某种接口,例如 Runnable、Callable,它允许延迟执行代码块。还有其他选项,但都不是简单的,例如使用动态代理。

tl;博士

在 Java 中不能以简洁的方式做到这一点。

于 2013-09-11T09:02:21.203 回答