Show Buttons
Share On Facebook
Share On Twitter
Share On Google Plus
Share On Linkdin
Share On Reddit
Share On Stumbleupon
Contact us
Hide Buttons

The difference between Rxjs combineLatest and withLatestFrom

When I started look­ing at ways to com­bine streams, one of the points of con­fu­sion for me was the sub­tle dif­fer­ence in the behav­ior of com­bineLat­est and with­Lat­est­From. Although they are both used to com­bine streams,the dif­fer­ence lies in terms of ‘WHEN’ the com­bined stream pro­duces data on the subscriber.

com­bineLat­est

When using com­bineLat­est, data is pro­duced on the sub­scriber when EITHER of the streams pro­duce data.
Lets see an example.

var streamA = Rx.Observable
    .interval(100 /* ms */)
    .take(3)
    .map(i => `A-${i}` );

var streamB = Rx.Observable
    .interval(50 /* ms */)
    .take(6)
    .map(i => `B-${i}` );

streamA
  .combineLatest(streamB)
  .subscribe( data => console.log(data) );

Con­cep­tu­ally, a mar­ble dia­gram of it would be as follows

/* Marble diagram */
/*
    One: -----A-----A-----A|
    Two: ---B---B---B---B---B---B|

 Result: ---X-X-X---XX--X-X-X---X|
*/

Notice how data it emit­ted on the Result stream when ANY of the streams involved emit data. Also notice that when both the streams emit data at the same time(as in the code exam­ple above), the result stream sees two imme­di­ate data points.

When using com­bineLat­est, the data of both the streams have an equal weigh­tage in terms of pro­duc­ing an output.


with­Lat­est­From

The with­Lat­est­From method is quite dif­fer­ent instead. You use a pri­mary stream to con­trol when the data is emit­ted on the result.

Think of with­Lat­est­From as a way to use a pri­mary stream to throt­tle the out­put of a sec­ondary stream.

var primary = Rx.Observable
    .interval(100 /* ms */)
    .take(3)
    .map(i => `A-${i}` );

var secondary = Rx.Observable
    .interval(50 /* ms */)
    .take(6)
    .map(i => `B-${i}` );

primary
  .withLatestFrom(secondary)
  .subscribe( data => console.log(data) );

Con­cep­tu­ally, a mar­ble dia­gram of it would be as follows

/* Marble diagram */
/*
    One: -----A-----A-----A|
    Two: ---B---B---B---B---B---B|

 Result: -----X-----X-----X|
*/

Notice how in this case, data is emit­ted only 3 times on the result stream because the pri­mary observ­able only emit­ted 3 data points. As expected, it com­bines with the lat­est value of the sec­ondary stream when emit­ting data on the result, just like com­bineLat­est does.

Hope this helps a bit in case you had the same confusion.

Ryan Sukale

Ryan is a UX engineer living in San Francisco, California.

You may also like...