每当触发新请求时,我都会有一个用例,应该取消/忽略任何已经在飞行中的http请求。
例如 :
- 当请求#1花费太长时间来响应/减慢网络连接时,请求(比如#2)进入。
- 在这种情况下,#2从服务器获得非常快速的响应,然后在任何时候,即使#1回复了HTTP响应的响应 应该忽略可观察性。
- 我面临的问题是,首先,组件显示来自请求#2的响应值,并在req#1完成时再次更新(这不应该发生)。
我认为switchMap取消obervables /维持发出可观察值的顺序。
摘自我的服务。
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' });
}
以上实施不起作用。有人可以找出这个用例的正确实现。
答案 0 :(得分:3)
您似乎正在创建多个可观察对象。从您的示例中不清楚,但似乎每次要发出请求时都会调用Observable.of
。这样每次都会创建一个 new Observable流,因此对于每个后续调用,您将获得一个新流,而前一个流不会被取消。这就是.switchMap
无效的原因。
如果您希望.switchMap
取消HTTP请求,则需要它们使用相同的可观察流。您要使用的源Observable取决于触发http请求的确切内容,但您可以使用Subject
之类的内容自行管理。
const makeRequest$ = new Subject();
const myResponse$ = makeRequest$.pipe(switchMap(() => this.service.getStuff()));
您可以订阅myResponse$
以获得回复。只要您想触发请求,就可以执行makeRequest$.next()
。
答案 1 :(得分:0)
我有以下代码摘录,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
}
}