LiveLoveApp logo

Publish Operator

A Shorter multicast() Operator

The publish() operator is nothing more than a shorter way for creating a ConnectableObservable compared to the multicast() operator.

How? The publish() operator creates the Subject instance for us.

Using publish()

Previously we created a new Subject and provided this to the multicast() operator:

const subject = new Subject<number>();
const multicasted = observable.pipe(
  multicast(subject),
  refCount()
) as ConnectableObservable<number>;

Using the publish() operator we no longer need to create a new Subject ourselves:

const multicasted = observable.pipe(
  publish(),
  refCount()
) as ConnectableObservable<number>;

Of course, we do not have a reference to the Subject that is created internally within the publish() operator, so if we need access to the Subject we'll need to stick with the multicast() operator.

Example

Here is a full example building off of the previous code with the publish() and refCount() operators:

import { ConnectableObservable, Observable } from 'rxjs';
import { publish, refCount } from 'rxjs/operators';

/* Create a new observable, providing the observer. */
const observable = new Observable<number>((observer) => {
  console.log('%cNew subscription created', 'background: #222; color: #bada55');

  let i = 0;
  const interval = setInterval(() => {
    observer.next(i++);
  }, 1000);

  return () => {
    clearInterval(interval);
  };
});

/** Create the ConnectableObservable. */
const multicasted = observable.pipe(
  publish(),
  refCount()
) as ConnectableObservable<number>;

/* Each subscription receives a copy of Observer. */
const subscription = multicasted.subscribe((value) =>
  console.log('First subscription', value)
);
subscription.add(
  multicasted.subscribe((value) => console.log('Second subscription', value))
);

/* Complete the observable after 5 seconds. */
setTimeout(() => subscription.unsubscribe(), 5000);

See example on codesandbox