最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Does Functional Reactive Programming in JavaScript cause bigger problems with listener references? - Stack Overflow

programmeradmin1浏览0评论

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:

  • If the subject has a life span shorter than (or equal to) the observer, I can just do subject.on('event', ...)
  • If the subject has a life span longer than the observer, I need to use 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 bees very important. If you bine that with web sockets, which are a perfect candidate for an event stream and most likely long lived, this bees 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.

  • How is this solved in the current frameworks?
  • Do the frameworks tie into the life-cycle of objects? If yes: how?

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:

  • If the subject has a life span shorter than (or equal to) the observer, I can just do subject.on('event', ...)
  • If the subject has a life span longer than the observer, I need to use 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 bees very important. If you bine that with web sockets, which are a perfect candidate for an event stream and most likely long lived, this bees 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.

  • How is this solved in the current frameworks?
  • Do the frameworks tie into the life-cycle of objects? If yes: how?
Share Improve this question edited Nov 3, 2014 at 21:38 EECOLOR asked Nov 3, 2014 at 19:37 EECOLOREECOLOR 11.2k3 gold badges44 silver badges76 bronze badges 7
  • 1 If you think this question should be closed, please add a ment. Maybe add a suggestion to make the question more specific. Or maybe a pointer to a place where this question is a better fit. If it's unclear, please ask questions. I really want to use FRP. – EECOLOR Commented Nov 3, 2014 at 21:35
  • Sorry I had to vote to close. This question is way too open ended. – JK. Commented Nov 3, 2014 at 21:47
  • @JK. Do you have any suggestions on improving the question? – EECOLOR Commented Nov 3, 2014 at 21:48
  • It's a bit broad, but actually a brilliant question. You've got an up-vote, not a close from me :-) – Bergi Commented Nov 3, 2014 at 21:49
  • I wonder if there is any one person who can answer this question with information on multiple current frameworks. And if not, how you will choose the accepted answer among different answers about different frameworks... – Apanatshka Commented Nov 4, 2014 at 10:38
 |  Show 2 more ments

1 Answer 1

Reset to default 12

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.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论