In JavaScript the observer pattern is used quite often. There is one tricky thing with it and that's the references the subject keeps of the observers. They require cleanup. For regular applications I use the following rules of thumb:
subject.on('event', ...)
observer.listenTo(subject, 'event', ...)
In the second case, the listenTo
is aware of the life-cycle of the observer and it will automatically remove the listeners when it's time for the observer to die.
In modern day SPA (Single Page Application) style, where only parts of the application are active at any time this is something that becomes very important. If you combine that with web sockets, which are a perfect candidate for an event stream and most likely long lived, this becomes even more important.
With FRP, having something like an event stream representing changing values over time, I am (without knowing it) creating a lot of listeners. Each filter
, map
and flatMap
creates a new stream that is tied (probably using a listener) to the previous one.
In my mind it seems quite tricky to determine how and when I need to remove those listeners. I can not imagine me being the first to think about this problem, yet I could not find much about this on the Internet.
I have seen some frameworks in other languages use weak references. JavaScript does not have the concept of weak references (WeakMap is not usable here). Even if it had though, it seems like a bad idea because it's unclear when garbage collection takes place.
Functional programming paradigm is built upon the idea that everything is a pure function. Reactive programming paradigm is built upon the idea that everything is a stream observer and observable philosophy.
While RxJs is a functional programming library, it is also a reactive programming library. Reactive programming allows us to deal with the asynchronous nature of JavaScript in a seamless and very elegant manner.
Functional reactive programming (FRP) is a programming paradigm for reactive programming (asynchronous dataflow programming) using the building blocks of functional programming (e.g. map, reduce, filter).
Alongside React and Vue, Angular is considered to be one of the top JS UI frameworks. However, it differentiates itself through a couple of factors. Unlike the other top 2, it's a full-blown framework, coming with everything you'd want a framework to have.
In RxJs, each Observer
will, by default, have a separate listener on the original event source. So, if you have
var s = $('#textInput').keyupAsObservable()
s.subscribe(subscriber1);
s.map(function() {}).subscribe(subscriber2);
You'll have two keyup listeners. You can use .publish().refCount()
to make an Observable
maintain a single connection to its source.
In Bacon.js, Observables always maintain a single connection to their source.
In both libraries the connection to the source is created lazily (when an Observer
is added) and removed automatically when the (last) Observer is removed. Therefore you don't have to manually manage the listeners.
However, in the case where the subject
has a longer life span than the Observer
, you'll have to make sure the observer stops its subscription when its lifespan ends, or you'll have a leak. Neither libraries have any "magical" way of managing this, because to the library, your Observer
is just a function.
Personally I often create an Observable
called death
or whatever to signal the end-of-life for the Observer and then instead of subscribing to the subject
I subscribe to subject.takeUntil(death)
.
Regarding Elm, my understanding is that you have set up your entire event network at once, so there's no possibility for leak; Observers
cannot be added at a later stage.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With