ReactiveX / rxjs

A reactive programming library for JavaScript
https://rxjs.dev
Apache License 2.0
30.7k stars 3k forks source link

Proposal: overload of BehaviorSubject #583

Closed roganov closed 8 years ago

roganov commented 8 years ago

While building apps with Rx, I have quite often had a need for an observable that remembers its latest value, but doesn't have an initial value. Now this can be achieved by using ReplaySubject(1), but ReplaySubject is 'heavier'. What I'm proposing is to extend BehaviorSubject so that when it didn't get passed and initial value, it would wait for first value to come in before emitting anything.

const bs = new BehaviourSubject();
bs.subscribe(::console.log); // would print 'undefined'

Proposal:

const bs1 = new BehaviourSubject();
bs1.subscribe(::console.log); // wouldn't print anything, waiting for the first event
const bs2 = new BehaviourSubject(1);
bs2.subscribe(::console.log); // would print '1'

This, to my understanding, is implemented, in RxJava's BehaviorSubject:

public static <T> BehaviorSubject<T> create()
public static <T> BehaviorSubject<T> create(T defaultValue)
kwonoj commented 8 years ago

Seems RxJS4 also have it, maybe simply not migrated yet? (or dropped for some reason? at least wasn't able to lookup issues)

mattpodwysocki commented 8 years ago

:-1: we have been over this in RxJS and declined it then

trxcllnt commented 8 years ago

@mattpodwysocki I know this is a dup of my pull from ~2 years ago, but perhaps we can introduce a new type, LatestSubject maybe?

mattpodwysocki commented 8 years ago

@trxcllnt yes, as I said before in the old PR that I was perfectly willing to make a new Subject type but was unwilling to change the meaning of the BehaviorSubject due to its downstream dependencies with publishValue etc

roganov commented 8 years ago

Yeah a new subject type would be OK. Or we could probably make ReplaySubject(1) fast (treat it as a special case).

paulpdaniels commented 8 years ago

Couldn't we just make all bounded buffers a special case and implement a circular buffer instead of doing splicing?

staltz commented 8 years ago

Actually you can hack around BehaviorSubject if you don't want the first init event.

const bs1 = new BehaviourSubject('ignore me');
const interface = bs1.filter(x => x !== 'ignore me');
interface.subscribe(::console.log); // wouldn't print anything, waiting for the first event

But I also think something like LatestSubject would be helpful. Maybe we could bikeshed on that name still, we could consider HoldSubject or KeepSubject, taking a bit of inspiration from Sodium which has the hold function, a bit similar to publishBehavior.

staltz commented 8 years ago

Yeah a new subject type would be OK. Or we could probably make ReplaySubject(1) fast (treat it as a special case).

@roganov ReplaySubject and BehaviorSubject have different semantics for observers after they complete. See https://github.com/ReactiveX/RxJS/issues/453

ghetolay commented 7 years ago

So I came to the exact same conclusion when I needed to use a publishReplay(1) but seems too heavy compared to a publishBehavior() + filter().

Is the idea of a new Subject dropped or are we just waiting for a PR ?

Also I don't like HoldSubject because it sounds exactly like the current BehaviorSubject behavior: meaning there is always a value. MaybeHoldSubject would fit better as it may be empty. I think LatestSubject is the more explicit.

lock[bot] commented 6 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.