vue 侦听器侦听对象属性_不删除侦听器–使用ListenerHandles
vue 偵聽器偵聽對象屬性
聽一個可觀察的實例并對它的變化做出React很有趣。 做一些必要的事情來打斷或結束這種聆聽會變得很有趣。 讓我們看看問題的根源和解決方法。
總覽
這篇文章將首先討論這種情況,然后再討論常見的方法和問題所在。 然后,它將提供解決大多數問題的簡單抽象。
盡管示例使用Java,但許多其他語言也存在缺陷。 提出的解決方案可以應用于所有面向對象的語言。 那些懶于自己在Java中實現抽象的人可以使用LibFX 。
情況
由Ky Olsen在CC-BY 2.0下發布 。
假設我們想聽聽屬性值的變化。 這很簡單:
不支持刪除的簡單案例
private void startListeningToNameChanges(Property<String> name) {name.addListener((obs, oldValue, newValue) -> nameChanged(newValue)); }現在假設我們要在特定間隔內中斷監聽或完全停止監聽。
保持參考
解決此問題的最常用方法是保留對偵聽器的引用,并保留對周圍屬性的引用。 根據具體的用例,實現會有所不同,但是它們都可以歸結為以下形式:
默認方式刪除偵聽器
private Property<String> listenedName; private ChangeListener<String> nameListener;...private void startListeningToNameChanges(Property<String> 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中存在的所有可觀察/偵聽器組合。
例如,讓我們看一下ObservableValue<T> / ChangeListener<? superT>的組合ChangeListener<? superT> ChangeListener<? superT> :
'ListenerHandles'中的一些方法
public static <T> ListenerHandle createAttached(ObservableValue<T> observableValue,ChangeListener<? super T> changeListener);public static <T> ListenerHandle createDetached(ObservableValue<T> 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 (用于許多語言,包括Java,Scala,Python,C ++,C#和更多語言)或ReactFX (或此介紹性文章 )以了解一些實現。
反射
我們已經看到,從可觀察對象中刪除偵聽器的默認方法會產生許多危害,需要避免。 偵聽器句柄抽象提供了解決許多問題的干凈方法,而LibFX提供了一種實現。
翻譯自: https://www.javacodegeeks.com/2015/01/dont-remove-listeners-use-listenerhandles.html
vue 偵聽器偵聽對象屬性
總結
以上是生活随笔為你收集整理的vue 侦听器侦听对象属性_不删除侦听器–使用ListenerHandles的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: realme 真我 GT5 手机“燃模式
- 下一篇: 苹果回应仅 USB-C AirPods