青浦做网站公司,wordpress 视频教程,做初中试卷的网站,龙口建网站价格vue 侦听器侦听对象属性听一个可观察的实例并对它的变化做出React很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。 总览 这篇文章将首先讨论这种情况#xff0c;然后再讨论常见的方法和问题所在。 然后#xff0c;它将提供解… vue 侦听器侦听对象属性 听一个可观察的实例并对它的变化做出React很有趣。 做一些必要的事情来打断或结束这种聆听会变得很有趣。 让我们看看问题的根源和解决方法。 总览 这篇文章将首先讨论这种情况然后再讨论常见的方法和问题所在。 然后它将提供解决大多数问题的简单抽象。 尽管示例使用Java但许多其他语言也存在缺陷。 提出的解决方案可以应用于所有面向对象的语言。 那些懒于自己在Java中实现抽象的人可以使用LibFX 。 情况 由Ky Olsen在CC-BY 2.0下发布 。 假设我们想听听属性值的变化。 这很简单 不支持删除的简单案例 private void startListeningToNameChanges(PropertyString name) {name.addListener((obs, oldValue, newValue) - nameChanged(newValue));
} 现在假设我们要在特定间隔内中断监听或完全停止监听。 保持参考 解决此问题的最常用方法是保留对侦听器的引用并保留对周围属性的引用。 根据具体的用例实现会有所不同但是它们都可以归结为以下形式 默认方式删除侦听器 private PropertyString listenedName;
private ChangeListenerString nameListener;...private void startListeningToNameChanges(PropertyString name) {listenedName name;nameListener (obs, oldValue, newValue) - nameChanged(newValue);listenedName.addListener(nameListener);
}private void stopListeningToNameChanges() {listenedName.removeListener(nameListener);
} 尽管这看起来不错但我确信这实际上是一个糟糕的解决方案尽管是默认解决方案。 首先额外的引用使代码混乱。 很难让他们表达出为什么要留在身边的意图因此它们降低了可读性。 其次它们通过向类添加新的不变式来增加复杂度该属性必须始终是添加了侦听器的属性。 否则对removeListener的调用将无提示地执行任何操作并且在将来的更改时仍将执行该侦听器。 放开这可能是讨厌的。 如果类很短则坚持不变性是容易的但如果变得越来越复杂则可能成为问题。 第三引用特别是该属性的引用邀请与它们进行进一步的交互。 这可能不是故意的但没有任何办法阻止下一个开发人员继续这样做请参阅第一点。 如果有人确实开始对该物业进行操作第二点将成为非常现实的风险。 这些方面已经使它不能成为默认解决方案。 但是还有更多 在许多类中必须这样做会导致代码重复。 最后上面的实现包含一个竞争条件。 侦听器句柄 大多数问题来自直接在需要中断/结束侦听的类中处理可观察对象和侦听器。 这是不必要的所有这些问题都可以通过一个简单的抽象来解决 ListenerHandle 。 ListenerHandle public interface ListenerHandle {void attach();void detach();
} ListenerHandle保留对可观察对象和侦听器的引用。 在调用attach()或detach()它会将侦听器添加到可观察对象或将其删除。 为了将此语言嵌入语言当前将侦听器添加到可观察对象的所有方法都应返回该组合的句柄。 现在剩下要做的就是为所有可能的情况实际实现句柄。 或者说服那些开发您喜欢的编程语言的人来做。 这留给读者练习。 注意这解决了上面提到的所有问题除了争用条件之外。 有两种方法可以解决此问题 处理实现可能本质上是线程安全的 可以实现一个同步装饰器 LibFX中的ListenerHandles 作为Java开发人员您可以使用LibFX 它支持三个级别的侦听器句柄。 功能了解ListenerHandles 添加侦听ListenerHandle时 LibFX的所有可实现此功能而不会与Java API冲突的功能都会返回ListenerHandle 。 以WebViewHyperlinkListener为例 将“ ListenerHandle”获取到“ WebViewHyperlinkListener” WebView webView;ListenerHandle eventProcessingListener WebViews.addHyperlinkListener(webView, this::processEvent);JavaFX实用程序 由于LibFX与JavaFX有紧密的联系可能会想到它提供了一个实用程序类该类将侦听器添加到可观察对象并返回句柄。 这适用于JavaFX中存在的所有可观察/侦听器组合。 例如让我们看一下ObservableValueT / ChangeListener? superT的组合ChangeListener? superT ChangeListener? superT ListenerHandles中的一些方法 public static T ListenerHandle createAttached(ObservableValueT observableValue,ChangeListener? super T changeListener);public static T ListenerHandle createDetached(ObservableValueT observableValue,ChangeListener? super T changeListener);ListenerHandleBuilder 在所有其他情况下即对于上面未涵盖的任何可观察/侦听器组合可以使用构建器来创建手柄 为自定义类创建“ ListenerHandle” // These classes do not need to implement any special interfaces.
// Their only connection are the methods doTheAdding and doTheRemoving,
// which the builder does not need to know about.
MyCustomObservable customObservable;
MyCustomListener customListener;ListenerHandles.createFor(customObservable, customListener).onAttach((obs, listener) - obs.doTheAdding(listener)).onDetach((obs, listener) - obs.doTheRemoving(listener)).buildAttached();React式编程 尽管这不是关于React式编程的文章 但仍应提及。 查看ReactiveX 用于许多语言包括JavaScalaPythonC C和更多语言或ReactFX 或此介绍性文章 以了解一些实现。 反射 我们已经看到从可观察对象中删除侦听器的默认方法会产生许多危害需要避免。 侦听器句柄抽象提供了解决许多问题的干净方法而LibFX提供了一种实现。 翻译自: https://www.javacodegeeks.com/2015/01/dont-remove-listeners-use-listenerhandles.htmlvue 侦听器侦听对象属性