kask
kask

Reputation: 1759

rxjs map operator evaluated for each subscriber

Why is the map operator evaluated for each subscriber instead of once?

const obs1 = Rx.Observable.interval(1000).take(1).map((x, i) => {
  console.log(i+1 + ':1 map')
  return 'obs1';
})

const obs2 = Rx.Observable.interval(1300).take(1).map((x, i) => {
  console.log(i+1 + ':2 map')
  return 'obs2';
})

const obs3 = Rx.Observable.interval(1700).take(2).map((x, i) => {
  console.log(i+1 + ':3 map')
  return 'obs3';
})

const view = obs1.combineLatest(obs2, obs3, (obs1, obs2, obs3) => {                 return obs1 + ', ' + obs2 + ', ' + obs3; });

// Every subscriber adds more calls to map - why is it called multiple     times at the same time ?

view.subscribe((value) => {
  console.log('sub1: ' + value)
});

view.subscribe((value) => {
  console.log('sub2: ' + value)
});

view.subscribe((value) => {
  console.log('sub3: ' + value)
});

I created a testcase here: http://jsbin.com/jubinuf/3/edit?js,console

Can I write this testcase differently to avoid this behaviour?

Upvotes: 6

Views: 752

Answers (2)

Kyle Kelley
Kyle Kelley

Reputation: 14144

Every subscriber will run through the Observable sequence. If you want everyone to get the resulting stream instead, use .publish().refCount().

http://jsbin.com/ditikonopi/edit?js,console

The .publish() will return an observable sequence that shares a single subscription to the underlying sequence. refCount() will stay connected to the source so long as there is at least one subscription.

Upvotes: 6

user3743222
user3743222

Reputation: 18665

Kyle answer is correct. publish().refCount() applied to all three observables will result in the map selector function not being reexecuted.

To elaborate a bit more on that answer, it is useful to understand the difference between hot and cold observables when you use Rxjs. In your case, all your observables obsX are cold, so they are 'restarted' on subscription. combineLatest subscribes under the hood to all 3, which is why map is reexecuted. Have a look here for an illustrated explanation. It is a common stumbling block for beginners but it is quite simple to understand.

Upvotes: 4

Related Questions