首页 文章

RxJs switchMap与角度HttpClient

提问于
浏览
1

每当触发新请求时我都有一个用例,应该取消/忽略任何已经在飞行中的http请求 .

For eg

当请求#1花费太长时间来响应/减慢网络连接时,会出现请求(比如#2) . 在这种情况下,#2从服务器获得非常快速的响应,然后在任何时候,即使#1返回响应,HTTP响应可观察应该被忽略 . 我面临的问题是,首先,组件显示来自请求#2的响应值,并在req#1完成时再次更新(这不应该发生) .

我认为switchMap取消了obervables /维护了可观察值的发出顺序 .

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

上述实现不起作用 . 有人可以找出这个用例的正确实现 .

2 回答

  • 0

    看起来你正在创建多个可观察对象 . 从你的例子中不清楚,但似乎你每次想要发出请求时都会调用 Observable.of . 这会每次创建一个新的Observable流,因此对于每个后续调用,您将获得一个新流,而前一个流不会被取消 . 这就是 .switchMap 无效的原因 .

    如果希望 .switchMap 取消HTTP请求,则需要它们使用相同的可观察流 . 您要使用的源Observable取决于触发http请求的确切内容,但您可以使用 Subject 之类的内容自行管理 .

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

    您可以订阅 myResponse$ 以获得响应 . 只要您想触发请求,就可以执行 makeRequest$.next() .

  • -1

    我有以下代码摘录,switchMap实现是成功的 .

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

相关问题