多次调用相同方法时取消方法调用

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

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

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


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

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

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

鉴于其他答案,并经过一些搜索,似乎确实没有库可以做我想要的。

我创建了一个并将其放在GitHub上。 这个问题的未来读者可能会发现它很有趣。

https://github.com/ThomasGirard/JDebounce

我认为它还不是很好,但至少它可以工作并且可以用声明的方式使用:

@Debounce(delayMilliseconds = 100) public void debouncedMethod(int callID, DebounceTest callback) { } 

如果不使用像执行器和期货那样的额外基础设施,这在Java中是无法解决的。 在Java中以语法简洁的方式解决这个问题是不可能的。

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

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

TL;博士

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

你需要什么称为去抖动 。 你应该检查jQuery Throttle / Debounce插件 (除了使用相同的命名空间之外,它完全独立于jQuery)。 去抖部分涵盖了你需要的东西:

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

Underscore.js具有相同的方法:

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

创建并返回传递函数的新debounced版本,该函数将推迟执行,直到自上次调用之后经过wait毫秒。 用于实现仅在输入停止到达后才会发生的行为。 例如:呈现Markdown注释的预览,在窗口停止resize后重新计算布局,等等。

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

[编辑]

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