Thursday, November 4, 2021

RxJS - merge and mergeMap

 

merge



Create a output Observable which concurrently emits values of source Observables. It means that 'merge' (unlike 'concat') will not wait for the previous source Observable to complete before subscribing the next source Observable. 


Ex:

 
const stream1$ = interval(1000).pipe(map(next => 'value from stream 1'));
  const stream2$ = interval(1000).pipe(map(next => 'value from stream 2'));

  // merge
  const result$ = merge(stream1$, stream2$);
  result$.subscribe(console.log);


Result:


value from stream 1
value from stream 2
value from stream 1
value from stream 2
value from stream 1
value from stream 2
...



Therefore, if the order does not matter, then 'merge' is a good choice.




Transform each value of source Observable to a new (inner) Observable, and the emitted values of those new (inner) Observables will be merged to the output Observable.


This is the marble diagram from RxJS official Doc.


Ex: If we want to save ALL clientX of cursor when clicking page.

 
  // Use it to track the emitted value from click event
let index = 0;

// Click event
fromEvent(document, 'click')
.pipe(
// Logging the # of click event
tap(() => console.log('click event #' + index)),
// Mapping the value from 'click event' to a special label
// '#index - clientX'
map((next: any) => '#' + index + ' - ' + next.clientX),
// Increasing #
tap(() => index++),
// Using mergeMap to subscribe all source Observable
// Also, we use the following code to simulate
// http calls with some random delay
mergeMap(
next =>
of(next).pipe(delay(Math.floor(Math.random() * 5) * 1000)))
)
// Subscribe it and logging the emitted value
.subscribe(console.log);


Result:


click event #0
click event #1
click event #2
#1 - 475
#0 - 475
#2 - 475



According to the result above, the emitted value from source Observable are not in order. 


No comments:

Post a Comment