javascript - 使用 Observables 为循环迭代中的每个元素分配从 api 调用接收的值
问题描述
我有一个 foreach 循环,我正在迭代并希望调用函数,这些函数将依次进行异步 api 调用并返回可以在 html 中呈现的值。
第一个函数调用getCurrentValue()将返回 currentTemperatureRef ,我最终想分配receivedCurrentValue并在 html 中呈现
第二个函数调用getDesiredValue1()将返回desiredValueToBeReturned,我最终想分配receivedDesiredValue1并在 html 中呈现
ts
myObj = { droppedItem: [] };
elements = [
{ elementId: 1, elementName: "name1" },
{ elementId: 2, elementName: "name2" },
{ elementId: 3, elementName: "name3" },
{ elementId: 4, elementName: "name4" }
];
this.elements.forEach(element => {
let receivedCurrentValue = this.getCurrentValue(element.name);
let receivedDesiredValue1 = this.getDesiredValue1(element.id);
this.myObj.droppedItem.push(receivedCurrentValue)
this.myObj.droppedItem.push(receivedDesiredValue1)
}
getCurrentValue(eleName){
//1st api(async api call)
var ref = this.helperService.getPointIdbyTags(this.existingObj, ['current',
'temp'], eleName)[0];
//2nd api(async api call which expects ref value from above api call)
this.siteService.getHisPointData(ref, 'current')
.pipe(
map(this.helperService.stripHaystackTypeMapping),
)
.subscribe(({ rows }) => {
if (rows.length > 0) {
this.currentTemperatureRef = rows[0].val;
}
});
}
getDesiredValue1(eleId){
//1st async api call
this.siteService.getScheduleParamsByRoomRef('temp and air and desired and
heating', eleId)
.subscribe(function (a) {
let row = a;
let pointId = this.helperService.stripHaystackTypeMapping(row['id']).split(' ')[0];
//2nd async api call expecting pointId from above api call
this.siteService.getHisPointData(pointId, 'current')
.subscribe(function (a) {
let rows = a.rows,
if (rows.length > 0) {
let desiredValueToBeReturned = rows[0].val;
)
}
)
}
}
html
<div *ngFor="let existingItem of myObj?.droppedItem">
<span>{{existingItem.receivedValue}}</span>
<span>{{existingItem.receivedDesiredValue1}}</span>
<span>{{existingItem.receivedDesiredValue2}}</span>
</div>
更新
当我尝试
getCurrentValue(eleName){
let roomObj = this.getRoomObj(eleName);
let equipRef = roomObj.map(equip => equip.entities.filter(entity => entity.entities.length > 0)[0])[0];
return this.helperService.getPointIdbyTags(this.buildings, ['current',
'temp'], equipRef.referenceIDs.room)[0].pipe(switchMap((res:any)=>{
//we don't want "res" else the response of
return this.siteService.getHisPointData(res, 'current')
.pipe(
map(this.helperService.stripHaystackTypeMapping),
)
}));
}
我在线收到错误=> return this.helperService.getPointIdbyTags(this.buildings, ['current', 'temp'],equipRef.referenceIDs.room)[0].pipe(switchMap(
错误类型错误:this.helperService.getPointIdbyTags(...)[0].pipe 不是函数
解决方案
我不太了解这个问题,但是您需要了解一些有关 forkJoin 和 switchMap 的知识。SwitchMap 当您需要根据另一个的响应进行两次调用时,它很有用。建筑变得像
callOne.pipe(
switchMap(resposeOfCallOne=>{
return callTwo(responseOfCallOne)
})
如果订阅您收到 callTwo 的响应
forkJoin 获取调用数组并在数组中返回结果
forkJoin([callOne,callTwo])
如果订阅你收到一个数组: res[0] 有 callOne 的响应, res[1] 有 callTwo 的响应
好吧,首先将您的函数 getCurrentValue 和 getDesiredValue1 转换为返回 observables
getCurrentValue(eleName){
return this.helperService.getPointIdbyTags(this.existingObj, ['current',
'temp'], eleName)[0].pipe(switchMap((res:any)=>{
//we don't want "res" else the response of
return this.siteService.getHisPointData(ref, 'current')
.pipe(
map(this.helperService.stripHaystackTypeMapping),
)
};
}
getDesiredValue1(eleId){
return this.siteService.getScheduleParamsByRoomRef('temp and air and desired and
heating', eleId).pipe(
switchMap((a:any)=>{
let row = a;
let pointId = this.helperService.stripHaystackTypeMapping(row['id']).split(' ')[0];
return this.siteService.getHisPointData(pointId, 'current')
}))
好吧,当我们有一个想要创建两个调用的元素时,我们将使用 forkjoin
我们要制作,forEach 元素创建两个调用,所以我们可以制作
this.elements.forEach(element => {
forkJoin([this.getCurrentValue(element.name),this.getDesiredValue1(element.id)])
.subscribe(([current,desired])=>{
element.current=current;
element.desired=desired;
})
})
我订阅用户 ([current,desired]) 但我们可以使用 res 并使用 element.current=res[0],element.desired=res[1]
如果我们愿意,我们甚至可以只订阅一个——现在我们有这么多订阅元素——
arrayOfCalls=[]
this.elements.forEach(element => {
arrayOfCalls.push(
forkJoin([this.getCurrentValue(element.name),this.getDesiredValue1(element.id)])
)
}
//then subscribe
arrayOfCalls.subscribe((fullRes:any[])=>{
fullRes.map((res,index)=>{
this.elements[index].currentValue=res[0]
this.elements[index].desiredValue=res[1]
})
})
推荐阅读
- python - 访问 Flask 测试响应中的所有 cookie
- maven - 库项目的存储库单元测试
- javascript - npm“crypto”模块的Nodejs加密问题
- javascript - 我使用 AngularJS 的 js 文件有问题:“未捕获的错误:[$injector:modulerr]”
- angular - Angular:如何在延迟加载的路由中使用外部模块
- r - 二元运算符错误的非数字参数
- c++ - 如何在每次 QTimer 发射时使用 QLabel
- python - 无服务器部署 - LogicalResourceId
- pyspark - 将 pyspark 行转置为列
- json - 如何在 Angular TypeScript 中忽略 JSON 数据中的变量