[英]How to properly flatten an stream of observables?
[英]How to switchMap a stream of 3 Observables
我必須將 3 個 Observable 流合並為一個。 我正在使用 Angular 和 Firebase,這是假設的工作方式......
第 1 步:我向 Firebase 發送查詢並接收array
。 我將使用特定屬性中的id來查詢Step 2的其他內容。
第 2 步:我使用第 1 步中的ID從另一個集合中獲取數據,為此我將收到另一個array
。 在這個數組中,我有Step 3需要的另一個ID 。
第 3 步:我需要使用第 2 步中提供的ID從數據庫中獲取 object。
為了讓這個工作,我使用switchMap()
但問題是我得到VOID
作為該方法的結果。
請幫忙!
更新:我更改了原始代碼。 有了這個,我可以看到console.log
,但是當我訂閱時,我什么也得不到。
getPanic() {
this.panicInfo = this.panicService.getPanic(this.checkID)
.pipe(
switchMap(panicSnaps => {
const requests = panicSnaps.map(panicSnap => {
const panicObj = {id: panicSnap.payload.doc.id, ...panicSnap.payload.doc.data() as any};
return this.panicService.getActions(panicObj.id)
.pipe(
tap({ complete: () => console.log('completed')}),
map(data => {
panicObj.actions = data;
console.log(panicObj);
return panicObj;
})
);
});
return forkJoin(requests);
}),
)
.subscribe();
}
拆分流是個好主意,這樣您就可以看到哪里出錯了。
getActionUsers(actionSnaps) {
const actions = actionSnaps.map(actionSnap => {
const actionsObj: PanicActions = {...actionSnap};
// need to return inside map
return this.userService.getUser(actionsObj.executor).pipe(
map(userSNAP => ({...actionsObj, ...userSNAP})) // combine only action and user here
);
});
// need to combine and return (deal with empty)
return actions.length ? combineLatest(...actions) : of([]);
}
getPanicActions(panicData) {
const panic = panicData.map(snaps => {
const panicObj: Panic = {...snaps.payload.doc.data()};
return this.panicService.getActions(panicObj.id).pipe(
switchMap(actionSnaps => this.getActionUsers(actionSnaps).pipe(
map(res => ({...panicObj, ...res})) // add panicObj here
))
);
});
// forkJoin only works on observables that complete, use combineLatest when they don't, also need to deal with empty
return panic.length ? combineLatest(...panic) : of([]);
}
getPanic() {
this.panicService.getPanic(this.checkID).pipe(
switchMap(panicData => this.getPanicActions(panicData))
).subscribe(data => {
// The panicInfo is of type 'Panic' but I get a TS Lint error that says:
// Type 'void[]' is missing the following properties from type 'Panic': id, checkId, city, geolocation, and 10 more
this.panicInfo = data;
});
}
測試這段代碼:
getPanic() {
this.panicService.getPanic(this.checkID)
.pipe(
switchMap((panicData: any[]) => forkJoin(
...panicData.map(snaps => {
const panicObj = { ...snaps.payload.doc.data() };
return this.panicService.getActions(panicObj.id).pipe(
switchMap((actionSnaps: any[]) => forkJoin(
...actionSnaps.map(actionSnap => {
const actionsObj: any = { ...actionSnap };
return this.userService.getUser(actionsObj.executor).pipe(
map(userSNAP => ({ ...panicObj, ...actionsObj, ...userSNAP })),
);
}),
)),
);
}),
)),
)
.subscribe(data => {
// The panicInfo is of type 'Panic' but I get a TS Lint error that says:
// Type 'void[]' is missing the following properties from type 'Panic': id, checkId, city, geolocation, and 10 more
this.panicInfo = data;
});
我在stackblitz上的例子
我不知道您在請求中收到什么數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.