kefirjs / kefir

A Reactive Programming library for JavaScript
https://kefirjs.github.io/kefir/
MIT License
1.87k stars 97 forks source link

Add documentation to "Kefir.pool" as "Rx.Subject equivalent" #306

Open abrakadobr opened 4 years ago

abrakadobr commented 4 years ago

I'm moving my project from RxJS to Kefir and got "problem" with "Rx.Subject equivalent" I found #165 . and #276 , but my situation is a bit different: I need multiple subscribers for one stream. Normal stream behavior doesn't allow this, same with Rx.Observer and this is absoultelly fine, and that's what RxSubjects are used for. I'm new with Kefir, so testing Kefir.pool for undocumented behavior of "multiple subscribers" was just idea of "if pool suuports multiple sources, so pool is not a 'normal stream' may be at also supports 'multile subscribers'"? And it works!

example:

const Kefir = require('kefir')

let s = Kefir.stream(obs=>{
  for (let i=0;i<10;i++)
    obs.emit(i)
  obs.end()
}).spy()

let pool = Kefir.pool()

pool.onValue(v=>{
  console.log('+++++ value',v)
}) //1st subscriber

pool.observe(v=>{
  console.log('----- value',v)
}) //2nd subscriber

pool.log() //3rd subscriber

pool.plug(s) 

I have no idea - it was designed, or this is kind of bug, but this is perfect behavior! :) Please, don't remove it, but document it - this is only one way (I found) to get multiple subscribers

rpominov commented 4 years ago

Actually in Kefir all observables support multiple subscribers. In your example it might seem otherwise because your stream emits events synchronously, meaning there's no delay between activation (first subscription) and emitting all events. So first subscriber receives the events, but by the time you add a second one they are already emitted.

If your stream looked like this:

let s = Kefir.stream(obs=>{
  let i = 0;
  const intervalIt = setInterval(() => {obs.emit(i); i++})
  return () => {
    clearInterval(intervalId);
  }
})

Then you could do the following and both subscribers would get the events:

s.onValue(v=>{
  console.log('+++++ value',v)
}) //1st subscriber

s.observe(v=>{
  console.log('----- value',v)
}) //2nd subscriber

More on it here https://kefirjs.github.io/kefir/#current-in-streams

abrakadobr commented 4 years ago

Nice, thanks for explanation. =) So, I'm using streams almost everywhere, and like "can't guarantee" - my streams will require async, or not (basically, thats why i'm useing streams - they unify for me sync/async), so pool gives me like "guarantied solution" for some situations, when sources can be syncronous and i need deliver event to multiple subscibers (and "end" is not required, ofc)

So, may be point somehow this behavor in docs?