How to handle/queue multiple same http requests with RxJs?

半城伤御伤魂 提交于 2020-01-01 06:02:01

问题


I am making an Angular 4 app. Components are subscribing Observable. Sometimes Observable call the same url. For example 'refresh Access Token' if needed before any http request. But if I make different 3 http requests, it will "refresh if needed" 3 times the refresh token.

So how to make only one http get to get a refreshed access token, and make the other observables 'wait' for the first one ? (I know 'wait' is not the good word for Observables).

        public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
            return this.getAccessToken().mergeMap(accessToken => {
              return this.http.get(url, options);
            });
          }

// And

this.get('www.myapi.com/one').subscribe(data=>console.log('one',data))
this.get('www.myapi.com/two').subscribe(data=>console.log('two',data))
this.get('www.myapi.com/three').subscribe(data=>console.log('three,data))

回答1:


It seems like you can use the share() operator that makes sure there's always only one subscription to the source Observable.

However this will require you to restructure your code because all observers need to use the same instance of share():

const sharedToken = this.getAccessToken().share();

public get(url: string, options?: RequestOptionsArgs): Observable<Response> {
  return sharedToken.mergeMap(accessToken => {
    return this.http.get(url, options);
  });
}



回答2:


Use an operator called forkJoin. If you are familiar with Promises this is very similar to Promise.all(). The forkJoin() operator allows us take a list of Observables and execute them in parallel. Once every Observable in the list emits a value the forkJoin with emit a single Observable value containing a list of all the resolved values from the Observables in the list

please go through the below example:

Import:

import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';

Let assume you have to get three pages

var pages:number[] = [1, 2, 3];

Or var pages:number[]=new Array(10).fill().map((v,i)=>i+1);

and then map them into an array of observables and forkJoin

Observable.forkJoin(
   pages.map(
      i => this.http.get('www.myapi.com/' + i)
        .map(res => res.json())
   )
).subscribe(people => this.people = people);

Please go Stack or forkJoin for more info.



来源:https://stackoverflow.com/questions/45416494/how-to-handle-queue-multiple-same-http-requests-with-rxjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!