使用flatMap

时间:2017-07-27 15:29:26

标签: javascript angular rxjs observable

我正在使用observable和flatMap运算符,我编写了一个方法,它调用并调用API并返回带有对象数组的observable。基本上我需要的是获取对象数组并处理每个对象,在处理完所有项之后,我想链接结果以使用我编写的另一个方法进行额外的API调用。以下代码可以满足我的需求:

  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,而是返回该数组上的每个对象项。我很感激你的帮助。

谢谢。

2 个答案:

答案 0 :(得分:5)

您想要的是.do()运算符,而不是flatMap()flatMap()将事件转换为另一个事件,实质上是将它们链接起来。 .do()只执行你指示它做的任何事情,以及事件中的每一次发射。

从您的代码中,有2个异步方法(调用api)和2个同步(processService)。你想要做的是:

  1. 调用第一个API(异步),等待结果
  2. 处理结果(同步)
  3. 调用第二个API(异步),等待结果返回
  4. 处理结果(同步)
  5. 因此你的代码应该是:

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

答案 1 :(得分:0)

我认为您遇到的问题是flatmap应该应用于可观察或承诺。在第二个代码示例中,您将返回flatmap运算符中的数据,然后将其传递给以下flatmap函数,而这些函数应返回observables。 例如:

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进一步澄清。