Reputation: 5268
I'm playing around with rxjs
trying to understand one concept: reactive programming supposed to be lazy. If no one subscriber is attached to an observable, it shouldn't produce values. Here is my example:
const Rx = require('rxjs')
const state = new Rx.Subject()
const changeStateLazy = (args) =>
Rx.Observable.of(args)
// some logic, e.g. REST requests
.do(val => state.next('new state'))
changeStateLazy(42)
const stateListener = state.subscribe(
val => console.log('state.next: ', val),
err => console.log('state.error: ', err),
() => console.log('state.complete'))
How to make the observable (which in function changeStateLazy
) lazy, i.e. run some logic...
and change the state only if a listener is attached to state
subject (in my case it's stateListener
)?
Upvotes: 0
Views: 3534
Reputation: 5268
Here is how I could manage that.
const Rx = require('rxjs')
const lazyStateModifier = new Rx.ReplaySubject(1)
.map(args => {
console.log('>some logic. args: ', args)
return {status: 'OK', result: 'new state'}
})
.map(res => res.result)
const state = new Rx.Subject().merge(lazyStateModifier)
const changeStateLazy = (args) =>
lazyStateModifier.next(args)
console.log('>invoke changeStateLazy')
changeStateLazy(42)
console.log('>subscribe')
state.subscribe(
val => console.log('state.next: ', val),
err => console.log('state.error: ', err),
() => console.log('state.complete'))
Hope there's a better solution, without merging every lazy observable to the state...
Upvotes: 1
Reputation: 2030
Not exactly sure what you want to achieve, but if you want to output the LAST value when an observer is subscribed, try "AsyncSubject".
const state = new Rx.AsyncSubject();
For AsyncSubject to work, it needs to call the complete method.
const changeState = () =>
Rx.Observable.of(1)
.subscribe(val => {
state.next('new state');
state.complete();
});
You may want to use "BehaviorSubject", "BehaviorSubject", etc. if you want it to behave differently.
Upvotes: 0