Angular组件与服务回调实现:慢网络下等服务返回值再执行后续逻辑
问题根因
你现在用setTimeout固定等待1秒的写法,本质是赌接口请求能在1秒内返回。网络波动、请求排队、带宽不足的时候,请求还没返回就触发getResult,自然只能拿到空结果。要实现“请求成功返回后再调用getResult”,核心是把异步请求的完成时机作为触发信号,完全抛弃固定延时的写法。
适配两种场景的实现方案
首先要先确认commonService里_getGlobalDiskaun方法的返回值类型,这是决定写法的核心:
- 场景1:方法返回Angular生态常用的
Observable(也就是普通Http请求封装的返回类型)
直接替换掉原来的setTimeout逻辑,订阅请求的成功回调即可,修改后的代码:
注意:如果项目使用Angular 14+版本,记得在组件getDiscount() { // 去掉无意义的临时数组,本来只传一个对象没必要push进数组 const requestParam = { price: Number(this.commonService.getPayments$.getValue()) }; this.commonService._getGlobalDiskaun(requestParam) .subscribe({ // 只有请求成功拿到响应后,才会执行这里的逻辑 next: () => { this.getResult(); }, // 补全错误分支,避免请求失败无任何提示 error: (err) => { console.error('获取全局折扣失败', err); } }) }ngOnDestroy生命周期里对这个订阅做退订处理,避免内存泄漏 - 场景2:方法返回原生
Promise
用async/await的写法逻辑更直观,新手更容易理解:async getDiscount() { const requestParam = { price: Number(this.commonService.getPayments$.getValue()) }; try { // await会暂停当前函数执行,直到这个Promise拿到成功返回值再继续往下走 await this.commonService._getGlobalDiskaun(requestParam); // 走到这行时,请求已经成功完成,直接调用getResult即可 this.getResult(); } catch (err) { console.error('获取全局折扣失败', err); } }
避坑提示
- 所有靠固定延时(setTimeout、setInterval轮询)等异步请求结果的写法,在生产环境都是不可靠的,延迟时长永远没法适配所有网络场景
- 如果当前
_getGlobalDiskaun方法既不返回Observable也不返回Promise,只是内部发完请求就无返回值,优先修改service层逻辑,把Http请求的返回值透传出来,不然上层组件永远拿不到“请求完成”的信号,没法做准确的时机判断
内容的提问来源于stack exchange,提问作者Fash
相关产品推荐
相关产品推荐

