Rxjs: switchMap behavior differs from Rx 4 flatMapLatest

Created on 31 Jul 2016  路  4Comments  路  Source: ReactiveX/rxjs

In the Operators Renamed or Removed section of the RxJS 4 to 5 Migration Guide, it is written that

  • flatMapLatest has been renamed to switchMap

but the the behaviors of these two operators differ for the simple sample code given below (adapted from the flatMapLatest docs. Is this difference expected (a feature) or is it a bug? If the former, it should probably be documented.

RxJS version:

  • 4.1.0 (flatMapLatest) vs
  • 5.0.0-beta.10 (switchMap)

Code to reproduce:

Here are JSBin sources: Rx 4 and Rx 5; the 5.x version is reproduced here:

var source = Rx.Observable
  .range(1, 2)
  .do(x => console.log('src: ' + x))
  .switchMap(x => Rx.Observable.of(x + 'a', x + 'b'));

var subscription = source.subscribe(
    x => console.log('Next: ' + x),
    err => console.log('Error: ' + err),
    () => console.log('Completed'));

Actual behavior:

Output for flatMapLatest is:

src: 1
Next: 1a
src: 2
Next: 2a
Next: 2b
Completed

Output for switchMap is:

src: 1
Next: 1a
Next: 1b
src: 2
Next: 2a
Next: 2b
Completed

Additional information:

If the map function argument is changed to x => Rx.Observable.of(x + 'a', x + 'b').delay(0) then both have the same behavior, generating output:

src: 1
src: 2
Done
Next: 2a
Next: 2b
Completed

Most helpful comment

This is actually not related to the flatMapLatest vs. switchMap and instead related to a change in the default scheduler used.

You can make v5 behave like v4 by providing the Rx.Scheduler.asap scheduler to both .range() and .of(): http://jsbin.com/juxeye/edit?js,console

AFAIK it's not possible to make Observable.of() in v4 behave like v5 because in v4 it does not accept a custom scheduler.

v4 defaults to Rx.Scheduler.async (now known in v5 as Rx.Scheduler.asap) but v5 defaults to no special scheduling at all; sometimes known as "recusive scheduling" which is just a fancy name for normal syncronous JavaScript.

For posterity, here are the name changes to the schedulers and their docs

The migration guide doesn't make this clear enough IMO, so that's something actionable for us I think.

All 4 comments

This is actually not related to the flatMapLatest vs. switchMap and instead related to a change in the default scheduler used.

You can make v5 behave like v4 by providing the Rx.Scheduler.asap scheduler to both .range() and .of(): http://jsbin.com/juxeye/edit?js,console

AFAIK it's not possible to make Observable.of() in v4 behave like v5 because in v4 it does not accept a custom scheduler.

v4 defaults to Rx.Scheduler.async (now known in v5 as Rx.Scheduler.asap) but v5 defaults to no special scheduling at all; sometimes known as "recusive scheduling" which is just a fancy name for normal syncronous JavaScript.

For posterity, here are the name changes to the schedulers and their docs

The migration guide doesn't make this clear enough IMO, so that's something actionable for us I think.

There is now a section in MIGRATION about how the default scheduling changed: https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md#default-scheduling-changed

This is actually not related to the flatMapLatest vs. switchMap and instead related to a change in the default scheduler used.

I had a suspicion that it my be unrelated to the operators themselves.

@jayphelps, thanks for the clear explanation and for updating the migration guide!

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings