簡體   English   中英

如何切換映射 3 個 Observables 的 stream

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM