递归renderer中异步HTTP.post请求返回滞后无法获取正确结果
问题根源
- 现有
renderer是同步执行逻辑,但condition4分支内的http.post是异步请求:代码执行到subscribe时只会注册请求回调,不会阻塞等待响应返回,会直接往下执行到return语句,此时异步回调还没触发,自然拿不到请求后递归计算的结果。 - 之前async/await方案不生效的核心原因有两点:
- Angular HttpClient返回的是RxJS Observable对象,不是原生Promise,直接await无法按预期等待请求完成
- 就算把请求转成Promise,整个递归调用链没有全部适配异步写法,同步分支返回普通值、异步分支返回Promise,执行时序依然会混乱
- 额外隐患:用类属性
this.result存储递归中间值的写法本身就不安全,异步场景下如果多次调用renderer,会出现变量互相覆盖的问题。
修复方案
- 移除
this.result中间变量,每个逻辑分支直接return计算结果,避免异步并发下的变量污染 - 将
renderer标记为async方法,全链路统一返回Promise格式的结果 - 用RxJS提供的工具把HttpClient返回的Observable转为Promise,通过await等待请求完成后再执行后续递归逻辑
修正后的代码如下:
// RxJS 7及以上版本引入lastValueFrom做转换,低版本可直接用Observable的toPromise()方法 import { lastValueFrom } from 'rxjs'; public async renderer(mappingField, jsonField, i): Promise<any> { if (condition1) { return ..... } if (condition2) { // 递归调用加await等待内层执行完成 return await this.renderer(new_mappingField, new_jsonField, i) } if (condition3) { return ..... } // 触发HTTP请求的分支 if (condition4) { // 等待POST请求返回结果 const res = await lastValueFrom(this.httpClient.post(url, proxyBody)); // 拿到响应数据后递归计算结果 const calcResult = await this.renderer(new_mappingfield, res["_source"][new_mappingfield.epart], i) console.log('请求完成,计算结果:', calcResult); return calcResult; } // 无匹配条件时的默认返回,可根据业务调整 return undefined; }
调用注意事项
改造后renderer是异步方法,所有调用该方法的位置都需要加await(需在async函数内)或者通过.then()接收计算结果,不能直接同步取返回值。
内容的提问来源于stack exchange,提问作者Fonty
相关产品推荐
相关产品推荐

