Ryan Teh 的 Answer 如果您想在一个提示中概括所有 http 请求,它就像一个魅力,因为它是一个 Catch All 解决方案。
在这里,我使用 Angular 8.2.4 和 rxjs 6.4.0 的足够导入来扩展它,因为会有很多用户在寻找 cut n' paste
对于创建新答案而不是评论,我深表歉意,我仍然没有足够的信任。
queue-interceptor.service.ts
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { RequestQueueService } from './request-queue.service';
@Injectable()
export class QueueInterceptorService implements HttpInterceptor {
constructor(private queueService: RequestQueueService) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.queueService.intercept(request, next);
}
}
request-queue.service.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpEventType } from '@angular/common/http';
import { Observable, ReplaySubject } from 'rxjs';
import { tap, catchError, switchMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class RequestQueueService {
private queue: ReplaySubject<any>[] = [];
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const requestQueueItem$ = new ReplaySubject<any>();
const result$ = requestQueueItem$.pipe(
switchMap(() => next.handle(request).pipe(
tap(req => {
if (req.type == HttpEventType.Response) {
this.processNextRequest();
}
}),
catchError(err => {
this.processNextRequest();
throw err;
})
))
);
this.queue.push(requestQueueItem$);
if (this.queue.length <= 1) {
this.dispatchRequest();
}
return result$;
}
private processNextRequest(): void {
if (this.queue && this.queue.length > 0) {
this.queue.shift();
}
this.dispatchRequest();
}
private dispatchRequest(): void {
if (this.queue.length > 0) {
const nextSub$ = this.queue[0];
nextSub$.next();
nextSub$.complete();
}
}
}
和 app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RequestQueueService } from './YOUR_SERVICES_DIRECTORY/request-queue.service';
import { QueueInterceptorService } from './YOUR_SERVICES_DIRECTORY/queue-interceptor.service';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [
RequestQueueService,
{ provide: HTTP_INTERCEPTORS, useClass: QueueInterceptorService, multi: true }
],
bootstrap: [AppComponent]
})
export class AppModule { }