Converting RxJS Observables to Async/Await
Source: Dev.to
Comparing Reactive and Asynchronous Streams: Equivalent Transformations
Asynchronous Programming: The Basics
Asynchronous programming allows a program to start an operation without waiting for it to complete immediately. The program continues to execute other tasks and is later notified when the asynchronous operation finishes. This is usually achieved through callbacks, Promises, or async/await. It is excellent for handling I/O operations such as network requests or file reading, where the wait time can be significant.
Reactive Streams: Reacting to Data
Reactive streams take a data‑oriented approach, focusing on how data is emitted, received, and transformed over time. A reactive stream is a sequence of events that can be observed and reacted to. Frameworks like RxJava, RxJS, and Reactor provide tools to create, combine, and transform data streams declaratively. Their main advantage is handling continuously arriving data in varying volumes, making them ideal for real‑time systems and streaming data processing.
Comparing the Approaches
| Feature | Asynchronous Programming | Reactive Streams |
|---|---|---|
| Focus | Non‑blocking execution of operations. | Data streams and reactivity. |
| Data Model | Generally works with single data or results. | Operates on streams (sequences) of data. |
| Notification | Callbacks, Promises, async/await. | Observers and Subscriptions. |
| Complexity | Less complex for simple operations. | Can be more complex to understand at first. |
| Use Cases | I/O, background tasks. | Real‑time systems, streaming data. |
| Main Advantage | Improved responsiveness. | Flexibility in handling data streams. |
Equivalent Transformations: Asynchronous vs. Reactive
Single Asynchronous Call (Promise) and Reactive Stream
Asynchronous (JavaScript with Promises):
async function fetchData() {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
console.log(data);
}
fetchData();
Reactive (RxJS):
import { fromFetch } from 'rxjs/fetch';
import { switchMap, of, tap } from 'rxjs';
fromFetch('https://api.example.com/data')
.pipe(
switchMap(response => {
if (response.ok) {
return response.json();
} else {
return of({ error: response.status });
}
}),
tap(data => console.log(data))
)
.subscribe();
In this example, the asynchronous fetch call is equivalent to a reactive stream that emits a single value after the request completes.
Mapping (Map) and Data Processing
Asynchronous (JavaScript with Promise.all):
async function processData() {
const results = await Promise.all([
fetch('https://api.example.com/data1').then(res => res.json()),
fetch('https://api.example.com/data2').then(res => res.json())
]);
const mappedResults = results.map(item => item.value * 2);
console.log(mappedResults);
}
processData();
Reactive (RxJS):
import { forkJoin, from } from 'rxjs';
import { switchMap, map } from 'rxjs/operators';
import { fromFetch } from 'rxjs/fetch';
forkJoin({
data1: fromFetch('https://api.example.com/data1').pipe(switchMap(res => res.json())),
data2: fromFetch('https://api.example.com/data2').pipe(switchMap(res => res.json()))
})
.pipe(
map(results => [results.data1.value * 2, results.data2.value * 2])
)
.subscribe(mappedResults => console.log(mappedResults));
Both examples demonstrate how to transform received data. In the asynchronous approach, Promise.all and Array.map are used; in the reactive approach, forkJoin (to combine streams) and the RxJS map operator are used.
Conclusion
Both asynchronous programming and reactive streams are powerful tools for building modern applications. The choice between them depends on the specific requirements of the project. Asynchronous programming is suitable for simple tasks where responsiveness is crucial, while reactive streams excel in scenarios involving continuous data streams and complex transformations. Understanding the equivalencies between these approaches lets you leverage their strengths and create robust, efficient applications. Combining the two techniques is often the key to success in complex systems.