MergeMap vs ConcatMap vs ExhaustMap vs SwitchMap vs ForkJoin
When dealing with the asynchronous nature of applications, handling multiple requests concurrently or managing nested requests becomes a common challenge.
In RxJS, observables play a crucial role, and to address these challenges, RxJS offers several functions, each with its own behavior. Let’s delve into each of them 🚴
Setup
Before we begin, let’s set up a basic code structure to better understand the concepts with live examples, bcz as they say “The obvious needs no evidence” ⚛️
filesArray = ['file1.json', 'file2.json', 'file3.json'];
filesObservable = from(this.filesArray);
constructor(private http: HttpClient) {}
ngOnInit() {
}
Here, filesArray
contains the names of files with JSON data, and we convert it to observables using from()
because all the methods we'll discuss work with observables, except for forkJoin
.
Method 1 : mergeMap()
A function that returns an Observable that emits the result of applying the projection function to each item emitted by the source Observable and merging the results of the Observables obtained from this transformation.
The result may or may not follow the sequential order of inner observable. 😐
mergeMapFunc() {
console.info("mergeMap");
this.filesObservable
.pipe(mergeMap((file) => this.getJSON(file)))
.subscribe((data) => console.log(data));
}
output : Content of file2, file3, file1 (no specific order). 😐
Method 2 : concatMap()
A function that returns an Observable that emits the result of applying the projection function to each item emitted by the source Observable and taking values from each projected inner Observable sequentially.
The result will follow the sequential order of inner observable. 😉
concatMapFunc() {
console.info("concatMap");
this.filesObservable
.pipe(concatMap((file) => this.getJSON(file)))
.subscribe((data) => console.log(data));
}
output : Content of file1, file2, file3 (sequential order). 😉
Method 3 : exhaustMap()
A function that returns an Observable containing projected Observables of each item of the source, ignoring projected Observables that start before their preceding Observable has completed.
The result will complete the first inner request ignoring the rest. 😯
exhaustMapFunc() {
console.info("exhaustMap");
this.filesObservable
.pipe(exhaustMap((file) => this.getJSON(file)))
.subscribe((data) => console.log(data));
}
output : Content of file1 only; file2 and file3 request calls are ignored. 😯
Method 4 : switchMap()
A function that returns an Observable that emits the result of applying the projection function to each item emitted by the source Observable and taking only the values from the most recently projected inner Observable.
The result will complete the most recent inner request ignoring the rest. 🤒
switchMapFunc() {
console.info("switchMap");
this.filesObservable
.pipe(switchMap((file) => this.getJSON(file)))
.subscribe((data) => console.log(data));
}
output : Content of file3 only; file1 and file2 request calls are ignored. 🤒
Method 5 : forkJoin()
forkJoin is an operator that takes any number of input observables which can be passed either as an array or a dictionary of input observables. If no input observables are provided (e.g. an empty array is passed), then the resulting stream will complete immediately.
forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables. 👌
forkJoinFunc() {
console.info("forkJoin");
forkJoin(this.filesArray.map((file) => this.getJSON(file))).subscribe(
(data) => console.log(data)
);
}
output : Content of file1, file2, & file3 in sequential order, merged together. 👌
Conclusion
In summary, understanding MergeMap, ConcatMap, ExhaustMap, SwitchMap, and ForkJoin in RxJS is crucial for managing asynchronous operations effectively:
- MergeMap merges results from multiple observables.
- ConcatMap maintains sequential order.
- ExhaustMap ignores new requests until the current one completes.
- SwitchMap emits values from the latest observable.
- ForkJoin waits for all observables to complete before emitting a combined result.
By choosing the appropriate operator, you can handle asynchronous tasks efficiently and build responsive applications in RxJS.
Below I am providing you links of a demo configured project
https://github.com/thesiddharthraghuvanshi/environment-variables-configuration-in-angular
Hope this article will help at some extent, please follow for more such articles.
Thankyou for your time & Happy Coding 😋