RxJs switchMap with angular HttpClient

|▌冷眼眸甩不掉的悲伤 提交于 2020-07-19 00:56:49

问题


I have a use case whenever a new request is triggered, any http requests that are already in flight should be cancelled / ignored.

For eg:

  • A request (say #2) comes in while the request #1 takes too long to respond / slow network connectivity.
  • In this case #2 gets a very quick response from server then at any point even if the #1 comes back with a response the HTTP response observable should be ignored.
  • The problem i face is, first the component displays response values from request #2 and gets updated again when req #1 completes (this should not happen).

I figured that switchMap cancels obervables / maintains the order in which the observable values are emitted.

excerpt from my service.ts

Obervable.of('myServiceUrl')
             .switchMap(url => this.httpRequest(url) )
              .subscribe( response => {
                   // implementation
                   /** Update an observable with the 
                       with latest changes from response. this will be 
                       displayed in a component as async */
                });


private httpRequest(url) {
        return this.httpClient.get('myUrl', { observe: 'response' });
}

The above implementation doesn't work. Could some one figure out the correct implementation for this usecase.


回答1:


It seems like you are creating multiple observables. It's unclear from your example, but it seems like you call Observable.of each time you want to make the request. This creates a new Observable stream each time, so for each subsequent call you get a new stream, and the previous one is not canceled. This is why .switchMap is not working.

If you want .switchMap to cancel the HTTP requests, you need them to use the same observable stream. The source Observable you want to use depends on what exactly is triggering the http requests, but you can manage it yourself using something like Subject.

const makeRequest$ = new Subject();
const myResponse$ = makeRequest$.pipe(switchMap(() => this.service.getStuff()));

You can subscribe to myResponse$ to get the response. Any time you want to trigger a request, you can do makeRequest$.next().




回答2:


I have the below code excerpt with which the switchMap implementation was successfull.

class MyClass {
    private domain: string;
    private myServiceUri: subject;
    myData$: Observable<any>;

        constructor(private http: HttpClient) {
            .....
            this.myServiceUri = new Subject();
            this.myServiceUri.switchMap(uri => {
                    return this.http.get(uri , { observe: 'response' })
                            // we have to catch the error else the observable sequence will complete
                            .catch(error => {
                                // handle error scenario
                                return Obervable.empty(); //need this to continue the stream
                            });
                    })
                    .subscribe(response => {
                        this.myData$.next(response);
                    });
        }

        getData(uri: string) {
            this.myServiceUri.next(this.domain + uri); // this will trigger the request     
        }

    }


来源:https://stackoverflow.com/questions/49036074/rxjs-switchmap-with-angular-httpclient

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