RxJS Mastery – Join Creation Operators Overview

RxJS join creation operators overview lesson title

The RxJS join creation operators are used to create Observables out of multiple Observables (except for partition where the opposite happens). In this post we want to compare them and give guidance on when to use which operator. The following operators belong to that family:

Main differences between the operators

Usually the basic functionality of the join creation operators is quite similar. They take multiple Observables as input, subscribe to them and emit values based on certain conditions. Once one of the input Observables runs into an error and emits that also the final Observable is emitting and error and stops.

The main difference of the operators is in the conditions that are used to decide which values are emitted:

  • combineLatest: as soon as every input Observable has emitted at least once the values are emitted as array. Every single new value on the input Observables causes another array that is emitted with the updated value.
  • concat: concat works on the input Observables in order and considers all its values. It only proceeds with the next Observable once a previous input Observable has completed.
  • forkJoin: it considers only one value of each input Observable. An array is emitted with the last value of each input Observable before its completion.
  • merge: it takes all the values from all input Observable and emits as soon as a new value arrives.
  • partition: a single input Observable is split into two output Observables based on a condition. Each value is emitted when it arrives.
  • race: only the single input Observable that emits first is considered. But all its values matter.
  • zip: It waits for the first value of every input Observable. As soon as the last value arrives an array of this first values is emitted. It repeats again by waiting for the second value of each input, and so on.

When to use which operator

The following decision tree is one variant to decide which operator to use in which situation:

You see in the tree that the condition which values are emitted is the main factor in deciding between the different operators. The partition operator is a bit special because it doesn’t really join, but split. And race is one operator that only takes into account a single one out of many input Observables. Finally, merge is the really lightweight operators among the join creation operators. It basically just forwards values as if they would come from a single Observable.