81 votes

Délai de demande par défaut et spécifique

Il est généralement souhaitable d'avoir un délai d'attente par défaut (par exemple 30s) qui sera appliqué à toutes les demandes et qui peut être modifié pour des demandes particulières. plus longtemps (par exemple, 600s).

Il n'y a pas de bon moyen de spécifier le délai d'attente par défaut dans le fichier Http service, à ma connaissance.

Quelle est la manière d'aborder cette question dans HttpClient service ? Comment définir un délai d'attente par défaut pour toutes les requêtes sortantes, qui peut être surchargé pour des requêtes spécifiques ?

163voto

estus Points 5252

Il semble que sans extension HttpClientModule les seuls moyens prévus pour les intercepteurs de communiquer avec les requêtes respectives sont les suivants params et headers objets.

Puisque la valeur du timeout est scalaire, elle peut être fournie en toute sécurité comme un en-tête personnalisé à l'intercepteur, où il peut être décidé si c'est le timeout par défaut ou spécifique qui doit être appliqué via RxJS. timeout opérateur :

import { Inject, Injectable, InjectionToken } from '@angular/core';
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Observable } from 'rxjs';
import { timeout } from 'rxjs/operators';

export const DEFAULT_TIMEOUT = new InjectionToken<number>('defaultTimeout');

@Injectable()
export class TimeoutInterceptor implements HttpInterceptor {
  constructor(@Inject(DEFAULT_TIMEOUT) protected defaultTimeout: number) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const timeoutValue = Number(req.headers.get('timeout')) || this.defaultTimeout;

    return next.handle(req).pipe(timeout(timeoutValue));
  }
}

Ceci peut être configuré dans votre module d'application comme :

...
providers: [
  [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }],
  [{ provide: DEFAULT_TIMEOUT, useValue: 30000 }]
],  
...

La demande est ensuite effectuée avec des timeout en-tête

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

Comme les en-têtes sont censés être des chaînes, la valeur du délai d'attente doit d'abord être convertie en chaîne.

Voici une démo .

Les remerciements vont à @RahulSingh et @Jota.Toledo pour avoir suggéré l'idée d'utiliser des intercepteurs avec timeout .

15voto

Rahul Singh Points 9890

En utilisant le nouveau HttpClient, vous pouvez essayer quelque chose comme ceci

@Injectable()
export class AngularInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    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);
        }
    });
  }
}

L'ajout d'un délai d'attente à la next.handle(req) qui est transmis.

En l'enregistrant dans AppModule comme

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

15voto

Jota.Toledo Points 11554

Vous pourriez créer un intercepteur global avec la valeur du délai de base comme suit :

import { Injectable } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';

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

Ensuite, vous devez enregistrer cet injectable dans le tableau des fournisseurs de votre module racine.

La partie la plus délicate serait de remplacer le temps par défaut (augmentation/diminution) pour des demandes spécifiques. Pour le moment, je ne sais pas comment résoudre ce problème.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X