我正在尝试在我的名为Conventions的组件中填充一个数组,这是一个约定数组。
每个组织都有一份合同清单,每份合同都有一个约定编号,有了这个编号,我便得到了约定。
我使用getOrganizationForUser获取当前组织,然后获取合同列表。 然后,我使用合同中的约定ID来调用第二个API以获取约定。
当前,我的代码如下所示:
public getOrganizationForUser(): Observable<Organization> {
return this.httpClient
.get<Organization>(`${c.serviceBaseUrl.sp}/organizationByUser`)
.pipe(catchError((err, source) => this.responseHandler.onCatch(err, source)));
}
public getById(id: number) {
return this.httpClient
.get<Convention>(`${c.serviceBaseUrl.sp}/conventions/` + id)
.pipe(catchError((err, source) => this.responseHandler.onCatch(err, source)));
}
ngOnInit() {
this.OrganizationService.getOrganizationForUser().subscribe((organization: Organization) => {
organization.contracts.forEach((contract) => {
this.conventionService.getById(contract.conventionId).subscribe((convention: Convention) => {
this.conventions.push(convention);
})
})
})
}
我知道我可以创建一个可观察对象数组,并使用Observable.forkJoin()
等待所有这些异步调用完成,但是我希望能够定义订阅回调
每个调用的函数,因为我需要对该过程的引用。关于如何解决这个问题有什么想法吗?
我尝试过使用此功能,但总是可以理解
getTasksForEachProcess(): Observable<Array<any>> {
let tasksObservables = this.organizationService.getOrganizationForUser().pipe(map((organization: Organization) => {
organization.contractOrganizations.map(contract => {
return this.conventionService.getById(contract.conventionId).subscribe(convention =>
this.conventions.push(convention)
)
});
})
);
return forkJoin(tasksObservables);
};
ngOnInit() {
this.getTasksForEachProcess().subscribe(item => {
console.log(item);
}
}
答案 0 :(得分:0)
首先,由于我不了解您的意思
,我不确定您真正想要实现的目标我希望能够为每个定义订阅回调函数 通话,因为我需要参考流程
无论如何,在您所描述的情况下,我会做这样的事情
public getOrganizationForUser(): Observable<Organization> {
return this.httpClient
.get<Organization>(`${c.serviceBaseUrl.sp}/organizationByUser`)
.pipe(catchError((err, source) => this.responseHandler.onCatch(err, source)));
}
public getById(id: number) {
return this.httpClient
.get<Convention>(`${c.serviceBaseUrl.sp}/conventions/` + id)
.pipe(catchError((err, source) => this.responseHandler.onCatch(err, source)));
}
ngOnInit() {
const obsOfObservables = this.OrganizationService.getOrganizationForUser()
.pipe(
map(organization => organization.contracts),
map(contracts => contracts.map(contract => this.conventionService.getById(contract.conventionId)))
);
obsOfObservables
.pipe(
switchMap(conventionObservables => forkJoin(conventionObservables))
)
.subscribe(
conventions => { // do stuff with conventions }
)
}
这里的要点如下。
通过getOrganizationForUser()
,您将获得一个发出组织的Observable。您要做的第一件事就是使用第一个map
运算符将Observable发出的对象转换为合同数组。
第二个map
运算符将合同数组转换为约定的可观察数组。为了执行此转换,我们在Observable的map
运算符内使用Array的map
方法。这可能有点令人困惑,但是值得理解。
如果我们在这里停止,那么我们拥有的是obsOfObservables
,即发出一个Observable数组的Observable。
然后,我们将obsOfObservables
发出的Observable数组传递给forkJoin
函数,该函数本身返回一个Observable。由于我们实际上对forkJoin
返回的Observable通知的内容感兴趣,即我们对约定感兴趣,因此我们需要将 switch 从第一个Observable切换到第二个Observable,通过switchMap
运算符完成。
最终结果是一个Observable,它返回约定数组。考虑添加常数obsOfObservables
作为澄清原因的尝试,并且完全没有必要(如Barney Panofsky所说)。
我还没有模拟整个过程,所以我希望我没有插入错误,但是或多或少这是我在这种情况下要使用的思考过程。
最后一点,当您在subscribe
中有subscibe
时,通常要多加怀疑。
答案 1 :(得分:0)
我同意Picci通过思考来回答的逻辑。这与他的提议略有不同,尽管像他一样,我并未对此进行严格测试,并且可能会有一些错误。
这样做的逻辑是,您最终想要的是一个约定数组,而从“ observables”产生一个数组就是“ zip”的作用。流程如下:
organization.contracts
从from
数组中创建可观察对象流。map
的约定,并使用contract.conventionId
属性使用API查找。代码如下:
ngOnInit() {
zip( this.OrganizationService.getOrganizationForUser()
.pipe(
map((organization: Organization) =>
from(organization.contracts).pipe(
map(contract => this.conventionService.getById(contract.conventionId))
)
)
)
)
.subscribe((conventions: Convention[]) => this.conventions = conventions)
}