亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

是否可以在 JavaScript 中創建不擁有訂閱的事件發射器?

是否可以在 JavaScript 中創建不擁有訂閱的事件發射器?

慕仙森 2023-07-06 18:27:43
考慮我們有一些系統的模塊 (M) 和事件發射器 (E),它們提供 M 所需的一些更新。當 M 訂閱 E 時,它將回調函數 (F) 傳遞給 E。此時 E 將引用 F,而 F 將引用參考 M (E → F → M)。這意味著由于事件發射器,M 無法被垃圾收集。但從概念上講,當 M 不再被系統引用時,它不需要 E 進行任何更新,因此 E 不應該阻止它被垃圾收集。在當今的 JavaScript 訂閱模型中,它是通過返回顯式處置器 (DF) 來解決的,DF 是一個取消特定訂閱的函數。但我認為這很糟糕,原因有兩個。首先,它打破了 JavaScript 的自然規則:當某些東西無法通過引用訪問時,該東西就會被垃圾收集。其次,處理器是一個額外的參考。所以,現在 DF 引用了 E,因此不僅 E 阻止 M 進行 gc,反之亦然(M → DF → E 和 E → F → M)。看來這是一個使用弱引用的好地方。但是,我無法弄清楚如何在 WeakMap 或 WeakSet 之上構建事件發射器。即使你把訂閱放在弱容器中,當你需要發出時,你仍然需要一些硬引用來取出它們。這完全抵消了弱容器的好處!我最好的想法是一個假設的“支持迭代的WeakSet”。除了通常的 API: 之外add,此類對象has還delete應該具有forEachWeak,它與通常的 forEach 一樣工作,并授予對迭代對象的臨時所有權。如果用戶不將此類對象提取到其他硬引用容器(如數組)中,這不會打破引用的弱點,并且仍然允許迭代。在事件發射器的情況下,此類發射器將能夠發出對訂閱的更新,而無需永久引用它們。那么,是否可以以這種方式或任何其他方式構建非擁有事件發射器?
查看完整描述

1 回答

?
人到中年有點甜

TA貢獻1895條經驗 獲得超7個贊

但從概念上講,當 M 不再被整個系統引用時,它不需要 E 進行任何更新

那要看。這只有在 M 完全被動的情況下才有效。一旦您想使用 M 實際執行某些操作,您就需要它來獲取更新,無論其他內容是否引用它。通過將 M 存儲在全局變量(?)中來保持訂閱活動并通過嘗試對其進行垃圾收集(這不是確定性的)來取消訂閱是相當困難的。另一方面,顯式處置器則清晰且簡單。

我無法弄清楚如何在 WeakMap 或 WeakSet 之上構建事件發射器。

這不可能。WeakMap/WeakSet實際上是ephemerons,它們不提供弱引用。


查看完整回答
反對 回復 2023-07-06
  • 1 回答
  • 0 關注
  • 137 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號