Requirement:
urls = [url1, url2, url3]
Fire all 3 urls parallely and paint the Dom in the sequnce of the urls list
ex: Fini
You can form a sequence with fetch and paint then forkJoin/Promise.all them
p1 = fetch(url1)
p2 = fetch(url2)
p3 = fetch(url3)
forkJoin(
from(p1).pipe(tap(_=>paint dom...))
from(p1).pipe(tap(_=>paint dom...))
from(p1).pipe(tap(_=>paint dom...))
).subscribe()
The best way to preserve order with async tasks like this is with concatMap.
The problem is that if we apply this alone, we lose the parallelisation. If we were to do something like this:
from(urls)
.pipe(
concatMap(x => fetch(x))
)
the second request is not fired until the first is complete.
We can get around this by separating out the map into its own operator:
from(urls)
.pipe(
map(x => fetch(x)),
concatMap(x => x)
)
The request will all be fired at the same time, and the results will be emitted in request order.
See Adrian's example adapted to use this approach below:
const { from } = rxjs;
const { concatMap, map } = rxjs.operators;
function delayPromise(val, delay) {
return new Promise(res => setTimeout(() => res(val), delay));
}
var delay = 3;
from([1, 2, 3]).pipe(
map(x => delayPromise(x, delay-- * 1000)),
concatMap(x => x)
).subscribe(result => { console.log(result); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>
I couldn't find anything that preserves the order so I came up with something a bit convoluted.
const { concat, of, BehaviorSubject, Subject } = rxjs;
const { delay, filter } = rxjs.operators;
const parallelExecute = (...obs$) => {
const subjects = obs$.map(o$ => {
const subject$ = new BehaviorSubject();
const sub = o$.subscribe(o => { subject$.next(o); });
return { sub: sub, obs$: subject$.pipe(filter(val => val)) };
});
const subject$ = new Subject();
sub(0);
function sub(index) {
const current = subjects[index];
current.obs$.subscribe(c => {
subject$.next(c);
current.obs$.complete();
current.sub.unsubscribe();
if (index < subjects.length -1) {
sub(index + 1);
} else {
subject$.complete();
}
});
}
return subject$;
}
parallelExecute(
of(1).pipe(delay(3000)),
of(2).pipe(delay(2000)),
of(3).pipe(delay(1000))
).subscribe(result => { console.log(result); });
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.4.0/rxjs.umd.min.js"></script>