Default and specific request timeout
通常最好将默认超时(例如30秒)应用于所有请求,并且可以为特定的较长请求(例如600秒)覆盖。
据我所知,没有很好的方法在
在
似乎没有扩展
由于超时值为标量,因此可以安全地将其作为自定义标头提供给拦截器,在拦截器中可以确定它是默认超时还是应通过RxJS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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, next: HttpHandler): Observable<HttpEvent> { const timeoutValue = req.headers.get('timeout') || this.defaultTimeout; const timeoutValueNumeric = Number(timeoutValue); return next.handle(req).pipe(timeout(timeoutValueNumeric)); } } |
可以在您的应用模块中进行配置,例如:
1 2 3 4 | providers: [ [{ provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true }], [{ provide: DEFAULT_TIMEOUT, useValue: 30000 }] ], |
然后使用自定义的
完成请求
1 | http.get('/your/url/here', { headers: new HttpHeaders({ timeout: `${20000}` }) }); |
由于标头应为字符串,因此应将超时值首先转换为字符串。
这是一个演示。
感谢@RahulSingh和@ Jota.Toledo建议使用与
作为其他答案的补充,请注意,如果您在开发机上使用代理配置,则代理的默认超时为120秒(2分钟)。对于更长的请求,您需要在配置中定义一个更高的值,否则这些答案都不起作用。
1 2 3 4 5 6 7 | { "/api": { "target":"http://localhost:3000", "secure": false, "timeout": 360000 } } |
您可以使用基本超时值创建全局拦截器,如下所示:
1 2 3 4 5 6 7 8 9 10 | 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<HttpEvent> { return next.handle(req).timeout(30000, Observable.throw("Request timed out")); // 30000 (30s) would be the global default for example } } |
之后,您需要在根模块的providers数组中注册此可注射物。
棘手的部分是要覆盖特定请求的默认时间(增加/减少)。目前,我不知道该如何解决。
使用新的HttpClient,您可以尝试这样的事情
1 2 3 4 5 6 7 8 9 10 11 | @Injectable() export class AngularInterceptor implements HttpInterceptor { intercept(req: HttpRequest, next: HttpHandler): Observable<HttpEvent> { 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); } }); } } |
向传递的
像
一样在AppModule中注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, HttpClientModule ], providers: [ [ { provide: HTTP_INTERCEPTORS, useClass: AngularInterceptor, multi: true } ] ], bootstrap: [AppComponent] }) export class AppModule { } |