我正在使用循环重复调用API并将相应的响应打印到对象中,但是在完成第二个订阅之前,循环继续进行并执行下一行代码。如何在循环继续进行之前适当地等待订阅结束?
我希望在第二个循环开始之前将电话数组完全填充。
getData() {
this.finaldata=[];
this.phone=[];
this.api.getSingleValue('/API/shift/app_name/' + this.application_name).subscribe((Response: any) => {
if (Array.isArray(Response) && Response.length > 0) {
for(let i=0; i<Response.length; i++){
this.api.getSingleValue('/API/person/' + Response[i].qlid).subscribe((res: any) => {
this.phone.push(res.contactNumber)
});
}
console.log(this.phone)
for(let i=0; i<Response.length; i++){
this.object={
"qlid": Response[i].qlid,
"entry_Type": Response[i].entry_Type,
"app_Name": Response[i].app_Name,
"shift_Start_Time": Response[i].shift_Start_Time,
"shift_End_Time":Response[i].shift_End_Time,
"startDate": Response[i].startDate,
"endDate": Response[i].endDate,
"reason": Response[i].reason,
"phone_no": this.phone[i]
}
this.finaldata.push(this.object);
}
console.log(this.finaldata)
this.rowData = this.finaldata;
}
else{
this.rowData=[];
alert('No Data To Display')
}
});
}
}
答案 0 :(得分:2)
尝试避免循环订阅和嵌套订阅。您可以使用RxJS运算符简化过程。
订阅工作流程:
调用this.api.getSingleValue('/API/shift/app_name/' + this.application_name)
并使用switchMap
将其切换为另一个可观察的状态。
在switchMap
中,使用iif
检查响应是否有效。
如果是,则将数组中的值映射到this.api.getSingleValue('/API/person/' + <response>.qlid))
数组,并使用forkJoin
合并可观察对象。使用map
运算符可以进一步处理响应,将值推送到this.finaldata
变量中并返回它。
如果不是,请使用throwError
运算符引发错误。
在订阅中,分别使用this.finaldata
和next
回调处理响应(error
变量)和错误。
尝试以下
getData() {
this.finaldata = [];
this.phone = [];
this.api.getSingleValue('/API/shift/app_name/' + this.application_name).pipe(
switchMap((Response: any) =>
iif(
() => Array.isArray(Response) && Response.length > 0,
forkJoin(Response.map(res => this.api.getSingleValue('/API/person/' + res.qlid))).pipe(
map(phone => {
this.phone = phone.map(number => number.contactNumber);
console.log(this.phone);
for(let i=0; i < Response.length; i++){
this.object = {
"qlid": Response[i].qlid,
"entry_Type": Response[i].entry_Type,
"app_Name": Response[i].app_Name,
"shift_Start_Time": Response[i].shift_Start_Time,
"shift_End_Time":Response[i].shift_End_Time,
"startDate": Response[i].startDate,
"endDate": Response[i].endDate,
"reason": Response[i].reason,
"phone_no": this.phone[i]
}
this.finaldata.push(this.object);
}
console.log(this.finaldata);
return this.finaldata;
})
),
throwError('Response was empty');
)
)
).subscribe(
(finaldata: any) => {
this.rowData = finaldata;
},
error => {
this.rowData = [];
alert('No Data To Display')
}
);
}
rowData
以外的成员变量如果仅使用this.finaldata
和this.phone
来保存此函数中的信息,则可以将它们全部替换为局部变量。另外,您可以使用数组forEach
函数,而不要手动循环数组。
getData() {
this.api.getSingleValue('/API/shift/app_name/' + this.application_name).pipe(
switchMap((Response: any) =>
iif(
() => Array.isArray(Response) && Response.length > 0,
forkJoin(Response.map(res => this.api.getSingleValue('/API/person/' + res.qlid))).pipe(
map(phones => {
const contactNumbers = phones.map(phone => phone.contactNumber);
let output = [];
Response.forEach((res, index) => {
output.push({
"qlid": res.qlid,
"entry_Type": res.entry_Type,
"app_Name": res.app_Name,
"shift_Start_Time": res.shift_Start_Time,
"shift_End_Time":res.shift_End_Time,
"startDate": res.startDate,
"endDate": res.endDate,
"reason": res.reason,
"phone_no": contactNumbers[index]
})
});
return output;
})
),
throwError('No Data To Display');
)
)
).subscribe(
(finaldata: any) => {
this.rowData = finaldata;
},
error => {
this.rowData = [];
alert(error)
}
);
}