2017-07-27 67 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()混淆的地方。