Angular请求因Spring Boot服务宕机超时,如何捕获并停止加载?
解决Angular请求超时(net::ERR_TIMED_OUT)无法捕获并关闭加载动画的问题
问题原因
当后端服务宕机时,浏览器触发的net::ERR_TIMED_OUT属于底层网络错误,默认情况下Angular HttpClient未设置超时时间,会导致请求长期处于pending状态,无法触发订阅的error回调,进而无法执行closeLoading()关闭加载动画。
解决方案
1. 给请求添加超时配置(局部方式)
在你的DataService的getData方法中,通过RxJS的timeout操作符设置超时时间,确保超时后能触发错误回调:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { timeout } from 'rxjs/operators'; @Injectable({ providedIn: 'root' }) export class DataService { constructor(private http: HttpClient) {} getData(detailParam: any) { return this.http.post('https://localhost:8080/report/data', detailParam) .pipe( timeout(5000) // 设置5秒超时,可根据业务需求调整时长 ); } }
2. 使用finalize操作符统一关闭加载动画
finalize操作符会在请求完成(无论成功、失败还是超时)时执行指定逻辑,避免在success和error回调中重复编写closeLoading(),同时覆盖所有场景:
import { finalize } from 'rxjs/operators'; // 组件中的请求代码 this.dataService.getData(detailParam).pipe( finalize(() => this.closeLoading()) // 无论请求结果如何都会执行 ).subscribe( (responseData: any) => { console.log('请求成功'); }, (error) => { console.error('请求失败:', error); // 可针对性处理超时错误 if (error.name === 'TimeoutError') { console.error('请求超时,请稍后重试'); } } );
3. 全局配置超时(可选)
如果希望所有请求都默认带有超时设置,可通过HTTP拦截器实现:
第一步:创建超时拦截器
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http'; import { timeout } from 'rxjs/operators'; @Injectable() export class TimeoutInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler) { return next.handle(req).pipe(timeout(5000)); // 全局设置5秒超时 } }
第二步:在模块中注册拦截器
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http'; import { TimeoutInterceptor } from './timeout.interceptor'; @NgModule({ imports: [HttpClientModule], providers: [ { provide: HTTP_INTERCEPTORS, useClass: TimeoutInterceptor, multi: true } ] }) export class AppModule { }
内容的提问来源于stack exchange,提问作者PandaPoPo
相关产品推荐
相关产品推荐

