TL;DR: Try concatAll and concatMap because they're more specific to the actual behavior than flatten and flatMap, because "flat" has a more general meaning. Also, there's popular precedent in Rx
RxJS has a precedent here, as concatMap and concatAll do the same thing in RxJS as what is proposed here, where flatMap (which changed to mergeMap in v5 because it's too ambiguous as to how it's "flattening") does something very different and very specific to observing pushed values.
Specifically this is the behavior of concatMap and concatAll in RxJS:
concatMap: (roughly speaking) maps to a new observables, and plays them in a serial fashion, one at a time, end to end.
concatAll: Takes a higher-order Observable (Observable<Observable>), and queues up each inner observable, playing them in a serial fashion, one at a time, end to end.
/**
* A test fixture that emits the passed values from a returned
* Observable one at a time, roughly one second apart, and completes
* after emitting the last value.
*/
function ob(...args) {
return new Observable(observer => {
let i = 0;
const id = setInterval(() => {
observer.next(args[i++]);
if (i >= args.length) observer.complete();
}, 1000);
return () => clearInterval(id);
});
}
const source = ob(
ob(1, 2),
ob(3, 4),
ob(5, 6),
);
const source2 = ob(1, 2, 3);
const mappingFn = n => ob(n, n + 1, n + 2);
const logger = { next(result) { console.log(result); } };
/* concatAll */
source.concatAll()
.subscribe(logger); // 1....2....3....4....5....6
/* concatMap */
source2.concatMap(mappingFn)
.subscribe(logger); // 1....2....3....2....3....4....3....4....5
/* mergeAll (aka flatten elsewhere) */
source.mergeAll()
.subscribe(logger); // 1.3.5....2.4.6 (roughly)
/* flatMap (now mergeMap in Rx 5) */
source2.mergeMap(mappingFn)
.susbcribe(logger); // 1.2.3....2.3.4....3.4.5.
As you can see, concatMap is more like Array.prototype.flatMap (proposed) than RxJS's flatMap is. "flat" doesn't makes as much sense in Observable-land because there is more than two dimensions to deal choose to flatten, there's also time. With an array, there, could only be two dimensions, the length of the array, and the depth. Because of that ambiguity, RxJS opted to go with something more specific and moved away from flatMap and named it mergeMap (which as you can see above is very different from the flatMap proposed here).
It's just a proposal as an alternative to "smoosh".
I feel like I've rambled, but I hope that gets the idea across.
TL;DR: Try
concatAllandconcatMapbecause they're more specific to the actual behavior thanflattenandflatMap, because "flat" has a more general meaning. Also, there's popular precedent in RxRxJS has a precedent here, as
concatMapandconcatAlldo the same thing in RxJS as what is proposed here, whereflatMap(which changed tomergeMapin v5 because it's too ambiguous as to how it's "flattening") does something very different and very specific to observing pushed values.Specifically this is the behavior of
concatMapandconcatAllin RxJS:concatMap: (roughly speaking) maps to a new observables, and plays them in a serial fashion, one at a time, end to end.
concatAll: Takes a higher-order Observable (Observable<Observable>), and queues up each inner observable, playing them in a serial fashion, one at a time, end to end.
As you can see,
concatMapis more likeArray.prototype.flatMap(proposed) than RxJS'sflatMapis. "flat" doesn't makes as much sense in Observable-land because there is more than two dimensions to deal choose to flatten, there's also time. With an array, there, could only be two dimensions, the length of the array, and the depth. Because of that ambiguity, RxJS opted to go with something more specific and moved away fromflatMapand named itmergeMap(which as you can see above is very different from theflatMapproposed here).It's just a proposal as an alternative to "smoosh".
I feel like I've rambled, but I hope that gets the idea across.