cujojs / most

Ultra-high performance reactive programming
MIT License
3.49k stars 231 forks source link

could fromEvent support .on() and .off() #345

Open ghost opened 7 years ago

ghost commented 7 years ago

Libraries like socket.io and jquery exposes .on() and .off() methods to add and remove listeners. RxJS supports these methods in addition to add/removeEventListener, could most support them too?

axefrog commented 7 years ago

Most promotes a declarative approach to this kind of thing. What that would mean is that subscribing to a stream would invoke .on() and disposing the stream would invoke .off(). Do you have a use case or code example that we could discuss?

ghost commented 7 years ago

I'm working on a project in which I have to attach the same handler to a set of elements. Using a library like jquery I would do something like this:

$('a').on('click', ev => {...})

I think that's a very common thing to do... In this case, I didn't need too much work to get this:

fromEvent('click', $('a'))
  .map(...)
  ....

I just had to alias out the on and off methods. I did this to get a real feeling of how the code would look like and I really liked it. But I don't think messing with third parties libraries in my code is such a good idea and there is also the case for socket.io. I've been watching a video series where they're using RxJS to build a wrapper around the socket.io api and I think that workflow is quite awesome. With RxJS it's possible to do that because it supports on/off to add listeners. I prefer most over RxJS and I would love to be able to do such integrations based on on/off.

axefrog commented 7 years ago

It's important to remember that there are different philosophies and approaches to programming. RxJS and jQuery both promote an imperative approach to writing software, and their APIs are therefore built around that mindset. With Most, you have just as much power to do these things as with other libraries; it's just that the approach is a little different.

The cleanest approach would be to implement a simple producer source. Here's an example from a project I'm working on: https://github.com/StreamScope/server/blob/develop/src/modules/drivers/event-driver.js#L13-L63 The connection is initialized when the source is run, and it is cleaned up when the subscription is disposed. Don't worry if it looks like more code than you're expecting; most of my code there surrounds the management of the socket client and what I'm doing with the data when it is received.

See lines 78-81 to see how I then consume the source. Note that you'll want to use multicast() to ensure that the connection is shared among streams, or each stream will end up establishing its own connection.

If you learn to write producers in this way for special cases not handled by the base library and community extensions, it'll give you a lot of power to handle whatever scenario you are presented with.

I recommend you also take a look at the architecture wiki page for a deeper understanding of what's going on here.

ghost commented 7 years ago

Cool. Thanks for the links. I quite a noob in frp and I'm sure these will help me. I'll read it all.