const get_name = user => fake_backend[user.id].pipe(map(name => ({...user, name})));
// ^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
// A B
//
// A: Simulate HTTP request latency to lookup an id and return a name
// B: Merge name into initial user object
merge(...users.map(get_name), 2).pipe(toArray()).subscribe(final_users => {
// ^ ^^^^^^^^^
// A B
//
// A: Concurrency. Maximum two HTTP requests at any one time.
// B: Accumulate each output into an array. Complete when merge is done.
console.log(final_users);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/7.2.0/rxjs.umd.min.js" integrity="sha512-MlqMFvHwgWJ1vfts5fdC2WzxDaIXWfYuAd9Tb2lobtF61Gk+HIRDrbtxgasBSM9lZgOK9ilwK9LqFIYEV+k0IA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script>
const {merge, of} = rxjs;
const {tap, delay, map, toArray} = rxjs.operators;
const users =
[ { id: 1
, userId: 111
, name: ''
, children: [3]}
, { id: 2
, userId: 111
, name: ''
, children: [4]}
, { id: 3
, userId: 333
, name: ''
, children: []}
, { id: 4
, userId: 444
, name: ''
, children: []}];
const fake_backend =
{ 1: of('Foo').pipe(delay(3000), tap(() => console.log('user 1 ✓')))
, 2: of('Bar').pipe(delay(2000), tap(() => console.log('user 2 ✓')))
, 3: of('Baz').pipe(delay(1000), tap(() => console.log('user 3 ✓')))
, 4: of('Bat').pipe(delay(1000), tap(() => console.log('user 4 ✓'))) };
</script>