RxJS: MergeMap with Preserving Input order

后端 未结 3 1036
悲哀的现实
悲哀的现实 2021-01-07 03:04

Requirement:

urls = [url1, url2, url3]

Fire all 3 urls parallely and paint the Dom in the sequnce of the urls list

 ex: Fini         


        
3条回答
  •  臣服心动
    2021-01-07 03:36

    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); });

提交回复
热议问题