Angular HttpClient predeterminado y tiempo de espera de solicitud específico

Por lo general, es deseable tener un tiempo de espera predeterminado (por ejemplo, 30 segundos) que se aplicará a todas las solicitudes y puede anularse para solicitudes más largas (por ejemplo, 600).

No hay una buena manera de especificar el tiempo de espera predeterminado en Http , que yo sepa.

¿Cuál es la forma de abordar esto en HttpClient ? ¿Cómo se define un tiempo de espera predeterminado para todas las solicitudes salientes, que puede anularse para las específicas?

Parece que sin extender las clases HttpClientModule , las únicas formas esperadas para que los interceptores se comuniquen con las solicitudes respectivas son params y objetos de headers .

Como el valor de tiempo de espera es escalar, se puede proporcionar de forma segura como un encabezado personalizado al interceptor, donde se puede decidir si es el tiempo de espera predeterminado o específico que debe aplicarse a través del operador de timeout RxJS:

 import { Observable } from 'rxjs/Observable'; import 'rxjs/add/operator/timeout'; const DEFAULT_TIMEOUT = new InjectionToken('defaultTimeout'); const defaultTimeout = 10000; @Injectable() export class TimeoutInterceptor implements HttpInterceptor { constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout) {} intercept(req: HttpRequest, next: HttpHandler): Observable> { const timeout = Number(req.headers.get('timeout')) || this.defaultTimeout; return next.handle(req).timeout(timeout); } } ... providers: [ [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }], [{ provide: DEFAULT_TIMEOUT, useValue: defaultTimeout }] ], ... 

La solicitud se realiza con un encabezado de timeout personalizado

 http.get(..., { headers: new HttpHeaders({ timeout: `${20000}` }) }); 

Como se supone que los encabezados son cadenas, el valor de tiempo de espera se debe convertir a una cadena primero.

Aquí hay una demostración .

Los créditos van a @RahulSingh y @Jota.Toledo por sugerir la idea de usar interceptores con timeout .

Usando el nuevo HttpClient puedes probar algo como esto

 @Injectable() export class AngularInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { return next.handle(req).timeout(5000).do(event => {}, err => { // timeout of 5000 ms if(err instanceof HttpErrorResponse){ console.log("Error Caught By Interceptor"); //Observable.throw(err); } }); } } 

Agregar un tiempo de espera a next.handle(req) que se transfiere.

Registrando en AppModule como

 @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [ [ { provide: HTTP_INTERCEPTORS, useClass: AngularInterceptor, multi: true } ] ], bootstrap: [AppComponent] }) export class AppModule { } 

Puede crear un interceptor global con el valor de tiempo de espera base de la siguiente manera:

 import { Injectable } from '@angular/core'; import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http'; @Injectable() export class AngularInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable> { return next.handle(req).timeout(30000, Observable.throw("Request timed out")); // 30000 (30s) would be the global default for example } } 

Luego debe registrar este inyectable en la matriz de proveedores de su módulo raíz.

La parte difícil sería anular el tiempo predeterminado (boost / disminuir) para solicitudes específicas. Por el momento, no sé cómo resolver esto.