This article will be a short one mainly on resolving / handling promises in sequence using RXJS. One such example would be fetching a series of data, one after another, but only after the current one resolves.
The go to RXJS operator to achieve this is ConcatMap. When our use case requires sequentiality, ie. queueing a set of events to be resolved in order, we can consider ConcatMap as a possible solution.
ConcatMap when paired with RXJS's Subject will present you an easily modifiable, readable, function that can be adapted to most use cases. Here's the code:
from([1, 2, 3]).pipe(
concatMap(id => {
const res$ = new Subject();
fetch(`url-to-api/${id}`)
.then(res => res.json())
.then(res => {
res$.next(res);
res$.complete();
});
return res$;
})
).subscribe();
In the ConcatMap operator, we return a Subject.
This way, we can control the flow of the stream, we can decide when is the time to complete the current event and go to the next. The next request will not fire until the current one completes, which we'll do so via .complete()
call.
In between the fetch response and the completion of the subject, it is the gap for us to perform any modifications, or actions that is required.
In closing, here's a codepen to demo the code above.
Top comments (1)
Your example can be simplified to:
Operators expecting an
ObservableInput<T>
, such asconcatMap
, automatically coerce promises to observables. And observables built from promises automatically complete when the promise resolves.From the rxjs source code:
If you wanted to modify the promise's response, you can do that with an async function. For example: