Angular中ForkJoin使用疑问:如何获取接口返回的指定嵌套字段
嘿,我来帮你梳理下这个问题的来龙去脉,以及对应的解决方案:
首先,先明确你的场景:你通过forkJoin并行发起了3个HTTP请求,每个请求返回的是包含单个对象的数组(这也是你需要加[0]才能拿到alertMessage的原因),而forkJoin会把这三个请求的响应打包成一个数组返回给你,也就是说最终赋值给this.alarms的data结构是这样的:
[ [ { alertMessage: '第一个告警内容', ... } ], // digId=4149的接口响应 [ { alertMessage: '第二个告警内容', ... } ], // digId=4719的接口响应 [ { alertMessage: '第三个告警内容', ... } ] // digId=4309的接口响应 ]
你最初遇到的问题
你用*ngFor="let alarm of alarms"循环时,每个alarm其实是单个请求的响应数组(比如第一个alarm就是[ { alertMessage: '第一个告警内容' } ]),理论上{{alarm[0].alertMessage}}是可以正确展示每个请求对应的告警信息的——你说“会为3个事件都获取到[0]元素”,可能是你误解了循环的逻辑?或者你原本就只想单独展示某一个告警,而非全部三个?
不过你后来的修改完全正确:如果你不需要循环展示三个结果,而是想单独取第一个请求的alertMessage,直接用{{alarms[0][0].alertMessage}}就可以——这里第一个[0]是取forkJoin返回数组里的第一个请求响应,第二个[0]是取该响应数组里的第一个对象,然后就能拿到它的alertMessage字段了。
关于你问的“是否可以打印数组中第一个元素的第一个元素?”
当然可以!在订阅的回调函数里,你直接就能打印:
parallel$.subscribe( data => { this.alarms = data; // 打印第一个请求响应的第一个元素的alertMessage console.log(data[0][0].alertMessage); // 或者直接打印整个第一个元素 console.log(data[0][0]); })
可选的优化建议
如果每个接口返回的始终是单个对象的数组,你可以在HTTP请求阶段就把响应转换成单个对象,这样后续的模板和逻辑处理会更简洁:
// 记得先导入map操作符:import { map } from 'rxjs/operators'; const parallel$ = forkJoin( this.http.get('http://ninjaopsapi?tablename=REF_OPS_ALARM&babylonref=' + this.digId).pipe( map(response => response[0]) // 直接把数组转成单个对象 ), this.http.get('http://ninjaopsapi?tablename=REF_OPS_ALARM&babylonref=' + this.digId2).pipe( map(response => response[0]) ), this.http.get('http://ninjaopsapi?tablename=REF_OPS_ALARM&babylonref=' + this.digId3).pipe( map(response => response[0]) ) );
这样forkJoin返回的data结构就变成了:
[ { alertMessage: '第一个告警内容', ... }, { alertMessage: '第二个告警内容', ... }, { alertMessage: '第三个告警内容', ... } ]
之后不管是循环展示还是单独取值都更简单:
- 循环展示所有告警:
<div *ngFor="let alarm of alarms"> <div>{{alarm.alertMessage}}</div> </div>
- 单独取第一个告警:
<div>{{alarms[0].alertMessage}}</div>
内容的提问来源于stack exchange,提问作者Stina Gerard

