2017-07-27 62 views
0

即時通訊使用observables和flatMap操作符,我寫了一個方法,它使API調用並返回一個包含對象數組的observable。基本上我需要的是獲取該對象數組並處理每個對象,在處理完所有項目後,我想鏈接結果以使用另一個我編寫的方法創建額外的API調用。下面的代碼做什麼,我需要:與flatMap鏈接的觀察值地圖

this.apiService.getInformation('api-query', null).first().flatMap((apiData) => { 
    return apiData; 
    }).subscribe((dataObject) => { 
    this.processService.processFirstCall(dataObject); 
    }, null,() => { 
    this.apiService.getInformation('another-query', null).first().subscribe((anotherQueryData) => { 
     this.processService.processSecondCall(anotherQueryData); 
    }); 
    }); 

但這種方法是不是從我的角度最佳,我想用flatMap但如果我做了以下

this.apiService.getInformation('api-query', null).first().flatMap((apiData) => { 
    return apiData; 
    }).flatMap((dataObject) => { 
    this.processService.processFirstCall(dataObject); 
    return [dataObject]; 
    }).flatMap((value) => { 
    return this.apiService.getInformation('another-api-query', null).first(); 
    }).subscribe((value) => { 
    this.processService.processSecondCall(value); 
    }); 

鏈這些呼叫做第二次API調用會爲對象的apiData數組上的每個項目執行一次。我知道我錯過或誤解了一些東西。但從這個線程的第二個答案Why do we need to use flatMap?我認爲第二個flatMap應該返回處理後的apiData,而不是返回該數組上的每個對象項。我將不勝感激。

謝謝。

回答

0

我認爲你遇到的問題是flatmap應該應用於observable或promise。在第二個代碼示例中,您將在flatmap運算符中返回數據,然後將其傳遞給以下flatmap函數,而這些函數應該返回observable。 例如:

this.apiService.getInformation('api-query', null).first() 
    .flatMap((dataObject) => { 
    return this.processService.processFirstCall(dataObject); 
    }).flatMap((value) => { 
    return this.apiService.getInformation('another-api-query', null) 
    }).subscribe((value) => { 
    this.processService.processSecondCall(value); 
    }); 

獲得進一步的澄清參見this post

3

你想要的是.do()運營商,而不是flatMap()flatMap()將把一個事件轉化爲另一個事件,實質上是鏈接它們。 .do()只是執行你指示它做的任何事情,對事件中的每一次發射。

從您的代碼中,有2個異步方法(調用api)和2個同步(processService)。你想要做的是:

  1. 呼叫轉移到第一API(異步),等待結果
  2. 處理結果(同步)
  3. 呼叫轉移到第二API(異步),等待結果回來
  4. 處理結果(同步)

因此你的代碼應該是:

this.apiService.getInformation('api-query', null)//step1 
    .first() 
    .do((dataObject) => this.processFirstCall(dataObject))//step2 
    .flatMap(() => this.apiService.getInformation('another-api-query', null))//step3 
    .first() 
    .do(value => this.processService.processSecondCall(value))//step4 
    .subscribe((value) => { 
     console.log(value); 
    }); 

我在評論中寫了對應於上面列表的步驟。我還清理了不必要的操作員(如你的第一個flatMap有點多餘)。

此外,如果您想要轉換數據,則應該使用.map()而不是.do()。我認爲這是你與.map().flatMap()混淆的地方。