Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sequentially execute observables and emit one result

I have an array of observables which I'm executing in parallel using:

let observables: Observable<any>[]

Observable.forkJoin(observables) 

This works perfectly, however, I need to execute the array of observables sequentially, and only emit one result if the last observable has been completed. That's when I tried to use

Observable.concat(observables)

But this returns multiple results, and not only one - combined - result which I get when using forkJoin. So I actually need a combination of the two.

I've tried to use the reduce functionality to execute them sequentially, like this:

return observables.reduce((previous, current) => {
  return previous.flatMap(() => current);
}, Observable.empty());

But with this solution the observables are not executed at all.

like image 961
Tom van Brienen Avatar asked Jan 20 '18 17:01

Tom van Brienen


2 Answers

Assuming that your observables emit singular values, not arrays, you could rework your current approach to something like:

return Observable.concat(...observables).reduce((acc, current) => [...acc, current], []);

or even shorter:

return Observable.concat(...observables).toArray();

In the case that they emit array values, you could do the following:

const source = Observable.concat(...observables).flatMap(list => list).toArray();
like image 133
Jota.Toledo Avatar answered Sep 21 '22 15:09

Jota.Toledo


As Jota.Toledo or Mateusz Witkowski showed in their answers, with the new syntax of RxJS you can do:

return concat(...observables).pipe(toArray());
like image 27
riorudo Avatar answered Sep 23 '22 15:09

riorudo