Monday 23 November 2020

Is it possible to create event emitter which does not own its subscriptions in JavaScript?

Consider we have some system's module (M) and event emitter (E) which provides some updates required by M. When M subscribes to E it passes callback function (F) to E. At that point E would have reference to F and F would have reference to M (E → F → M). It means that M cannot be garbage collected because of event emitter. But conceptually, when M becomes unreferenced from across the system, it does not require any updates from E, so E should not prevent it from being garbage collected.

In today's JavaScript subscription model it is solved by returning explicit disposer (DF) which is a function that do unsubscription for that particular subscription. But I think that's bad for two reasons. First, it breaks natural rule of JavaScript: when something is not accessible by references that thing becomes garbage collected. Second, disposer is an additional reference. So, now DF references E, so not only E prevents M from gc, but vice versa as well (M → DF → E and E → F → M).

It seemes that this is a good place to use weak references. However, I cannot figuire out how to build event emitter on top of WeakMap or WeakSet. Even if you put subscriptions in weak container, you still need some hard references to take them out when you need to emit. This completely nullifies benefits of weak containers!

My best idea is a hypothetical «WeakSet which supports iteration». In addition to usual API: add, has and delete such object should have forEachWeak, which works just usual forEach and grants temporary owning over iterated objects. If user would not extract such objects into other hard ref container (like Array) this does not break weakness of references and still allow to iterate over. In case of event emitter, such emitter would have an ability to emit updates to subsctiptions without having them permanently referenced.

So, is it possible to build non-owning event emitter in this or any other manner?



from Is it possible to create event emitter which does not own its subscriptions in JavaScript?

No comments:

Post a Comment