我与observables和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,而不是返回该Array上的每个对象项。我会很感激的。

谢谢。

最佳答案

您想要的是.do()运算符,而不是flatMap()flatMap()将把一个事件转换为另一个事件,并实质上将它们链接起来。 .do()只需执行您指示执行的操作,即可处理事件中的每个发射。

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


调用第一个API(异步),等待结果
处理结果(同步)
调用第二个API(异步),等待结果返回
处理结果(同步)


因此,您的代码应为:

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()感到困惑的地方。

关于javascript - 使用flatMap链接可观察对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45355108/

10-16 14:27