Angular中如何实现接口每5秒轮询状态、10次重试后触发告警
实现方案
你可以借助RxJS内置的轮询、重试相关操作符实现需求,同时优化原有的嵌套订阅问题,改写后的完整代码如下:
// 首先引入需要的RxJS操作符 import { concatMap, take, retry, delay, finalize, tap } from 'rxjs/operators'; getRecognitionById() { this.loaderService.show(null, true); const MAX_RETRY_COUNT = 10; const RETRY_DELAY = 5000; this.vendorWebApiService.createRecognition(this.executiveChangeId) .pipe( take(1), // 拍平嵌套订阅 concatMap(res => { return this.vendorWebApiService.getRecognition(res.taskRequestId, this.executiveChangeId) .pipe( take(1), // 状态校验,不符合要求就抛出错误触发重试 tap(recognitionResponse => { const validStatus = ['completed', 'failed']; if (!validStatus.includes(recognitionResponse.jobStatus)) { throw new Error('status pending'); } }), // 重试配置:最多10次,每次间隔5秒 retry({ count: MAX_RETRY_COUNT, delay: (error, retryCount) => { // 只有是状态未就绪的错误才重试,其他错误直接抛出 if (error.message === 'status pending' && retryCount <= MAX_RETRY_COUNT) { return delay(RETRY_DELAY); } throw error; } }), // 请求结束后统一隐藏加载态 finalize(() => { this.loaderService.hide(); }) ) }) ) .subscribe({ next: (recognitionResponse) => { if (recognitionResponse.jobStatus === "completed") { this.recognitionData = recognitionResponse; this.getLatesFeedback(); } if (recognitionResponse.jobStatus === "failed") { alert('任务执行失败'); } }, error: () => { // 重试10次后仍未得到有效状态的告警 alert('任务状态查询超时,请稍后重试'); } }) }
关键改动说明
- 移除了原有的嵌套订阅,使用
concatMap操作符将串行的请求逻辑拍平,避免回调地狱 - 新增状态校验逻辑:查询到任务状态不是
completed/failed时主动抛出错误,触发重试机制 - 通过
retry操作符配置重试规则:最多重试10次,每次间隔5秒,只有状态未就绪的场景才会触发重试 - 新增
finalize操作符统一处理加载态隐藏逻辑,无论请求成功、失败、重试结束都会执行 - 统一在subscribe的error回调中处理重试10次后仍未得到有效状态的告警逻辑
如果你使用的是RxJS 6及更早版本,
retry操作符不支持对象格式的配置参数,可以替换为retryWhen操作符实现相同的重试规则。
内容的提问来源于stack exchange,提问作者Eugene Sukh
相关产品推荐
相关产品推荐

