目标是迭代ID集合,为每个ID进行HTTP调用。对于每个ID,我使用带有返回Observable的get()方法的服务。每次调用get()方法时,我都会订阅返回的Observable并尝试将结果推送到一个数组中,最终会将其传递给另一个新操作的方法。
相关服务方式:
public get(departmentId: number): Observable<IDepartmentModel> {
return super.get<IDepartmentModel>(departmentId);
}
注意:超类正在利用Angular Http,经过充分测试并确认其工作正常。逻辑的问题不在这里......
相关组件方法: 请注意在forEach中多次调用的departmentService.get()调用。
setInitialDepartmentsAssignedGridData(): void {
this.settingsForDropdownSelectedCompanyId = this.userForm.get('defaultCompany').get('defaultCompanyId').value;
let departments: IDepartmentModel[] = [];
this.userService.user.getValue() //confirmed: valid user is being pulled back from the userService (logic is fine here..)
.userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId) // getting a valid match here (logic is fine here..)
.departmentIds.forEach(deptId => this.departmentService.get(deptId).first().subscribe(dept => { // getting a valid department back here (logic is fine here...)
departments.push(dept); // HERE LIES THE PROBLEM
}));
this.setDepartmentsAssignedRowData(departments);
}
setDepartmentsAssignedRowData(departments: IDepartmentModel[]): void {
console.log('setDeptAssignedRowData called'); // confirmed: method is getting called...
console.log(departments); // confirmed: fully-composed collection of departments logged to the console...
departments.forEach(dept => {
console.log(dept);
}); // Y U NO WORK!?
departments.map((department) => {
console.log(department); // Y U NO WORK?
this.departmentAssignedRowData.push({
departmentId: department.id,
departmentName: department.name
});
});
this.departmentAssignedGridOptions.api.setRowData(this.departmentAssignedRowData);
}
问题是,虽然登录到控制台的是一个完全组合的部门 - 对象数组,但它不是真的&#34;那里&#34; ;传递给setDepartmentsAssignedRowData
的是一个空数组。
我确定发生的事情是,在将departments数组传递给第二个方法之前,异步操作尚未完成。我在网上看到的一些内容是使用forkJoin
,但我无法看到在这种背景下的情况。我也读过concatMap
可能会有效,但在这种情况下,我还不确定如何做到这一点......
在这种情况下,我如何利用RxJS确保预期的,完全合成的部门阵列真正准备好传递?
感谢您提供的任何见解。非常感谢帮助!
答案 0 :(得分:4)
你是对的,你需要forkJoin
let observableArray = this.userService.user.getValue()
.userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId)
.departmentIds.map(deptId => this.departmentService.get(deptId)) // map is building out an array of observables
这将是您要并行创建的http请求可观察数组。现在您可以将此数组传递给forkJoin
。
Observable.forkJoin(...observableArray)
forkJoin的返回将是来自observableArray
的结果数组。 forkJoin
中的observableArray
中的所有可观察对象都已完成(因此,当所有http请求都已完成时)let observableArray = this.userService.user.getValue()
.userCompanies.find(comp => comp.companyId === this.settingsForDropdownSelectedCompanyId)
.departmentIds.map(deptId => this.departmentService.get(deptId));
Observable.forkJoin(...observableArray).subscribe(res => {
// res = [resId0, resId1, resId2, ..., resIdX];
});
将不会向序列中的下一个运算符发出
总而言之,代码将是
forkJoin
您提到将结果传递给另一个运算符。如果该运算符是您传递数据数组的另一个http请求(来自Observable.forkJoin(...observableArray)
.flatMap(res => {
return this.otherApi(res);
})
.subscribe(res => {
// res is the result of the otherApi call
});
),那么您可以使用flatMap
运算符。
flatMap
otherApi
会将您的api请求链接在一起。所以正在发生的事情是
val one = List(50, 10, 17, 8, 16)
val two = List(582, 180, 174, 159, 158)
one.zip(two).map {
case (a, b) => a.toDouble/b.toDouble
}
)