[英]How to cancel ongoing HTTP requests when there's a new requests in angular 6 with rxjs 6
I'm having below RxnsSearchService
and RxnsSearchHitCountService
, two HTTP services in my app. 我的应用程序下面有两个
RxnsSearchService
和RxnsSearchHitCountService
,两个HTTP服务。
handling two requests with forkJoin
like below code. 使用
forkJoin
处理两个请求,如下面的代码所示。
constructor( private rxnsSearchService: RxnsSearchService, private rxnsSearchHitCountService: RxnsSearchHitCountService ) { } const rxnsObservable: Observable<Array<any>> = this.rxnsSearchService.getReactions(this.searchParams, filters); const headCountObservable: Observable<number> = this.rxnsSearchHitCountService.getHitCount(this.searchParams, filters); forkJoin([rxnsObservable, headCountObservable]).pipe().subscribe((results) => { //handling results }, error => { console.log(error); });
I want to cancel the ongoing old requests whenever there is a new request comes. 每当有新请求出现时,我都想取消正在进行的旧请求。 can anyone help me, to make it work around?
谁能帮助我,使它变通?
export class RxnsSearchService { sub: Subject<any> = new Subject(); constructor(private httpClient: HttpClient) {} getReactions(params: Params, offset: number, perPage: number, filters: any) { const body = { filters: filters, query: params.query }; return this.httpClient.post(environment.rxnsSearch, body).pipe( map((response: Array<any>) => { return response; }), catchError(error => { console.log(error); return throwError(error); }) ); } }
export class RxnsSearchHitCountService { constructor(private httpClient: HttpClient) {} getHitCount(params: Params, filters: any) { const body = { filters: filters, query: params.query, }; return this.httpClient.post(environment.rxnsSearchHitCount, body).pipe( map((response: number) => { return response; }), catchError(error => { console.log(error); return throwError(error); }) ); } }
I'll go through the general approach of how to do it, with a simplified example. 我将通过一个简化的示例介绍如何做到这一点的一般方法。 Say we currently have this:
说我们目前有这个:
public getReactions() {
this.http.get(…)
.subscribe(reactions => this.reactions = reactions);
}
The way to ensure that old requests are cancelled is by instead emitting on some subject: 确保取消旧请求的方法是改为发出某些主题:
private reactionsTrigger$ = new Subject<void>();
public getReactions() {
this.reactionsTrigger$.next();
}
Now we have an observable representing the stream of events triggering a new request. 现在,我们有了一个可观察到的代表触发新请求的事件流。 You can now implement
OnInit
to something like this: 现在,您可以将
OnInit
实施为以下形式:
public ngOnInit() {
this.reactionsTrigger$.pipe(
// Use this line if you want to load reactions once initially
// Otherwise, just remove it
startWith(undefined),
// We switchMap the trigger stream to the request
// Due to how switchMap works, if a previous request is still
// running, it will be cancelled.
switchMap(() => this.http.get(…)),
// We have to remember to ensure that we'll unsubscribe from
// this when the component is destroyed
takeUntil(this.destroy$),
).subscribe(reactions => this.reactions = reactions);
}
// Just in case you're unfamiliar with it, this is how you create
// an observable for when the component is destroyed. This helps
// us to unsubscribe properly in the code above
private destroy$ = new Subject<void>();
public ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
The line 线
switchMap(() => this.http.get(…)),
in your case might actually switch the events to the forkJoin
: 在您的情况下,实际上可能会将事件切换到
forkJoin
:
switchMap(() => forkJoin([rxnsObservable, headCountObservable])),
if you want a single event stream to trigger both requests anew. 如果您希望单个事件流重新触发两个请求。
It would be helpful to see a code snippet that shows the actual trigger of the HTTP requests, but it's most likely a UI component that calls a function on click. 看到一个显示HTTP请求实际触发的代码段将很有帮助,但是很可能是一个UI组件,它在单击时调用一个函数。
The way you would solve this with RxJS 6 is by using a Subject
for receiving the click events and then using the switchMap
operator to cancel unfinished requests in order to prevent backpressure. 使用RxJS 6解决此问题的方法是使用一个
Subject
来接收click事件,然后使用switchMap
运算符取消未完成的请求以防止背压。 Here is an example: 这是一个例子:
private clickSubject$: Subject<void> = new Subject();
constructor() {
this.clickSubject$
.pipe(switchMap(() => forkJoin([rxnsObservable, headCountObservable])))
.subscribe((results) => // handling)
}
onClick() {
this.clickSubject$.next(undefined);
}
If you have multiple places where you want to execute the http request, then emit into the subject with: this.clickSubject$.next(undefined)
; 如果您有多个要执行http请求的地方,则使用以下方法进入主题:
this.clickSubject$.next(undefined)
;
You can simply use the debounce operator in RxJs: 您可以在RxJs中简单地使用debounce运算符:
debounce(1000);
its a method provided in to set a delay in milliseconds before sending any request, 它提供了一种在发送任何请求之前设置延迟(以毫秒为单位)的方法,
The example replaces all the requests fired in 1000ms with only one request. 该示例仅用一个请求替换了1000ms内触发的所有请求。
For further detail: 有关更多详细信息:
fromEvent(input, 'input').pipe(
map((e: any) => e.target.value),
debounceTime(500),
distinctUntilChanged()
).subscribe(
(data) => {
this.onFilterTable({column: fieldName, data});
}
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.