通常,需要有默认超时时间(例如30秒),该时间将应用于所有请求,并且可以覆盖特定的longer个请求(例如600秒).

据我所知,在Http服务中没有指定默认超时的好方法.

如何在HttpClient服务中实现这一点?如何为所有发出的请求定义一个默认超时,该超时可以被特定请求覆盖?

推荐答案

似乎在不扩展HttpClientModule个类的情况下,拦截器与相应请求通信的唯一预期方式是paramsheaders个对象.

由于超时值是标量值,因此可以安全地将其作为自定义头提供给拦截器,在拦截器中可以确定它是默认超时还是特定超时,应该通过RxJS timeout运算符应用:

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 = req.headers.get('timeout') || this.defaultTimeout;
    const timeoutValueNumeric = Number(timeoutValue);

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

这可以在您的应用程序模块中进行配置,如下所示:

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

然后使用定制的timeout报头完成请求

http.get('/your/url/here', { headers: new HttpHeaders({ timeout: `${20000}` }) });

由于头应该是字符串,所以应该首先将超时值转换为字符串.

这是a demo美元.

学分归@RahulSingh和@Jota.托莱多建议使用timeout个拦截弹.

Angular相关问答推荐

Angular material 输入字段中的图标未显示

CDK虚拟滚动由于组件具有注入属性而在滚动时看到错误的值

我应该对我想要在我的Angular 17+组件中显示的任何变量使用信号吗?

所有返回缺少权限或权限不足的FireBase项目.

等待可观察性完成后再调用下一个

Angular6:RxJS switchMap 运算符未按预期工作

RxJs 中的空闲可观察对象在幕后做了什么?

在更改检测之前调用创建的间谍

带有重定向的Angular 2 AuthGuard服务?

Angular2 ngFor跳过第一个索引

EmptyError: no elements in sequence

为什么我们需要`ngDoCheck`

使用 Angular 2 新路由更改页面标题

Angular 5 中 value 和 ngValue 的区别

Angular2material对话框自动关闭

Angular 2 Material 2 日期 Select 器日期格式

@HostBinding 与 Angular 中的变量类

单元测试错误:无法从同步测试中调用 Promise.then

如何从materialAngular使用分页器?

'Observable' 类型上不存在属性 'filter'