|
| 1 | +# Day 14 - Combining Sequences Part Deux |
| 2 | + |
| 3 | +In the [previous entry](../13/readme.md), we covered combining Observable sequences together using `zip`, `combineLatest` and `withLatestFrom`. Today, we'll be looking at two other ways of combining sequences, with `concat` and `merge`. |
| 4 | + |
| 5 | +## Combining sequences with concat |
| 6 | + |
| 7 | +The first operator we will look at today is `concat`, which is to combine the sequences, by waiting until the end before starting the next sequence. This keeps all values in order from the sequences no matter when they were emitted. Let's walk through an example of `concat`. |
| 8 | + |
| 9 | +```typescript |
| 10 | +import { concat, of } from 'rxjs'; |
| 11 | + |
| 12 | +const num1$ = of(1, 2); |
| 13 | +const num2$ = of(3, 4); |
| 14 | +const num3$ = of(5, 6); |
| 15 | + |
| 16 | +const num$ = concat(num1$, num2$, num3$); |
| 17 | +const subscription = num$.subscribe({ |
| 18 | + next: item => console.log(item) |
| 19 | +}); |
| 20 | +// 1 |
| 21 | +// 2 |
| 22 | +// 3 |
| 23 | +// 4 |
| 24 | +// 5 |
| 25 | +// 6 |
| 26 | +``` |
| 27 | + |
| 28 | +As you will notice, the next sequence is triggered by the previous sequence finishing, thus putting the sequences in order. But, we're dealing with collections over time, so when we're dealing with events such as move movements, that's not super useful, so let's do a concurrent combining of sequences. |
| 29 | + |
| 30 | +## Combining sequences with merge |
| 31 | + |
| 32 | +In order to do concurrent combining of sequences into a single sequence, we have the `merge` operator. This allows us to merge any number of Observables, but also control the concurrency via adding a Scheduler, or a maximum number of concurrent sequences. |
| 33 | + |
| 34 | +```typescript |
| 35 | +merge(...args: Observable[]): Observable |
| 36 | +merge(...args: Observable[], maxConcurrent: number): Observable; |
| 37 | +merge(...args: Observable[], scheduler: SchedulerLike): Observable; |
| 38 | +``` |
| 39 | + |
| 40 | +To make this more concrete, let's take the `interval` calls from the previous lesson, and merge them together. Note how the sequences are combined with the third sequence firing first, followed by the first, and then the second. |
| 41 | + |
| 42 | +```typescript |
| 43 | +import { interval, merge } from 'rxjs'; |
| 44 | +import { map, take } from 'rxjs/operators'; |
| 45 | + |
| 46 | +const num1$ = interval(1000).pipe(map(x => `First: ${x}`), take(3)); |
| 47 | +const num2$ = interval(1500).pipe(map(x => `Second: ${x}`), take(3)); |
| 48 | +const num3$ = interval(500).pipe(map(x => `Third: ${x}`), take(3)); |
| 49 | + |
| 50 | +const num$ = merge(num1$, num2$, num3$); |
| 51 | +const subscription = num$.subscribe({ |
| 52 | + next: item => console.log(item) |
| 53 | +}); |
| 54 | +// Third: 0 |
| 55 | +// First: 0 |
| 56 | +// Third: 1 |
| 57 | +// Second: 0 |
| 58 | +// Third: 2 |
| 59 | +// First: 1 |
| 60 | +// Second: 1 |
| 61 | +// First: 2 |
| 62 | +// Second: 2 |
| 63 | +``` |
| 64 | + |
| 65 | +We could control the amount of concurrency with `merge` via the last parameter. In fact, we could turn `merge` into `concat` by setting the max concurrency at 1. |
| 66 | + |
| 67 | +```typescript |
| 68 | +import { interval, merge } from 'rxjs'; |
| 69 | +import { map, take } from 'rxjs/operators'; |
| 70 | + |
| 71 | +const num1$ = interval(1000).pipe(map(x => `First: ${x}`), take(3)); |
| 72 | +const num2$ = interval(1500).pipe(map(x => `Second: ${x}`), take(3)); |
| 73 | +const num3$ = interval(500).pipe(map(x => `Third: ${x}`), take(3)); |
| 74 | + |
| 75 | +const num$ = merge(num1$, num2$, num3$, 1); |
| 76 | +const subscription = num$.subscribe({ |
| 77 | + next: item => console.log(item) |
| 78 | +}); |
| 79 | +// First: 0 |
| 80 | +// First: 1 |
| 81 | +// First: 2 |
| 82 | +// Second: 0 |
| 83 | +// Second: 1 |
| 84 | +// Second: 2 |
| 85 | +// Third: 0 |
| 86 | +// Third: 1 |
| 87 | +// Third: 2 |
| 88 | +``` |
| 89 | + |
| 90 | +Despite the sequences themselves being asynchronous, we didn't subscribe to the next one until the first sequence was finished. Now that we have some of the basics down of combining sequences, we will get into the whole `mergeAll`, `concatAll`, and of course all the *Map operators like `concatMap`, `mergeMap`, `switchMap` and others. Stay tuned! |
0 commit comments