Angular中HttpClient发起GET请求直接订阅正常,使用pipe(map)却不触发
问题根因
- RxJS冷Observable运行特性:HttpClient返回的流为冷流,只有存在订阅者时,才会发起实际HTTP请求,同时pipe中挂载的所有操作符逻辑才会触发执行。
- 现有代码存在两处直接逻辑断点:
- 调用
.pipe(...)生成的新流没有任何订阅者,属于悬空流,所有下游map处理逻辑自然不会运行 getDrugList方法未将pipe处理后的Observable返回给调用方,即使外部预期订阅该方法的返回结果,也无法获取到可订阅的对象
- 调用
解决方案
根据业务场景二选一即可:
方案1:将处理后的流返回给外部调用方
在pipe链路前增加return语句,将处理后的Observable抛出,由调用方完成订阅,示例代码:
public getDrugList(drugName: string, depth: number = 1) { const url = '<my-url>'; // 新增return,将处理后的流返回给外部 return this.httpClient.get<Model[]>(url, { params: { depth: depth.toString(), code: '<my-code>', drugName: drugName.trim(), } }).pipe( map(models => models.flat()), map(models => { const nodes = this.getNodesFromModels(models); const edges = this.getEdgesFromModels(models); console.log(edges); console.log(nodes); return { nodes, edges }; }) ); }
调用方使用时直接订阅即可:
this.getDrugList('测试药品').subscribe(result => { // result为处理后的{ nodes, edges }结构,后续业务逻辑正常编写即可 })
方案2:方法内部直接处理结果,无需返回流
在pipe链路末尾主动完成订阅,示例代码:
public getDrugList(drugName: string, depth: number = 1) { const url = '<my-url>'; this.httpClient.get<Model[]>(url, { params: { depth: depth.toString(), code: '<my-code>', drugName: drugName.trim(), } }).pipe( map(models => models.flat()), map(models => { const nodes = this.getNodesFromModels(models); const edges = this.getEdgesFromModels(models); console.log(edges); console.log(nodes); return { nodes, edges }; }) ).subscribe(result => { // 内部处理{ nodes, edges }的后续逻辑 }); }
注意:如果选择内部主动订阅的方案,建议搭配
takeUntil等操作符,在组件/服务销毁时取消订阅,避免内存泄漏。
内容的提问来源于stack exchange,提问作者shockedeel
相关产品推荐
相关产品推荐

