Search code examples
rxjsreactivex

map v.s. flatmap when promise is involved


I am studying

  • operator map v.s. flatmap
  • how to add promise into observable chain.

Then I constructed 4 different versions of var source as below. version 1, 3 works as expected, while version 2, 4 fail oddly.

My code has also been added in => js bin

Could someone tell what is wrong with my code?

Thanks, Xi

console.clear();
var p = new Promise((resolve, reject) => {
  setTimeout( () => {
    resolve('resolved!');
  } , 1000);
});

var source = Rx.Observable.interval(200).take(3)
.flatMap(x => Rx.Observable.timer(500).map(() => x))   //version 1, works OK
// .flatMap(x => Rx.Observable.timer(500).map((x) => x))  // version 2, not OK, returns => 0, 0, 0
// .map(x => p.then( s => console.log(s)));                  // version 3, works OK 
// .flatMap(x => p.then( s => console.log(s)));                  // version 4, not OK, error occurs


source.subscribe(x => console.log(x.toString()));

Solution

  • .flatMap(x => Rx.Observable.timer(500).map((x) => x))
    

    returns "0", "0", "0" because timer emits 0 after 500 ms and map takes that value as input x and returns it with (x) => x. In the previous line, x was not redeclared in the map, so it came from flatMap.

    .flatMap(x => p.then( s => console.log(s)));
    

    gives an error because a promise emits the return value of the then callback. That's console.log(s) which being a statement evaluates to undefined. So the flatMap gives an Observable of undefined, undefined, undefined. When the first reaches the subscribe it tries to do undefined.toString and errors out.