Javascript 用平面图链接观测值

Javascript 用平面图链接观测值,javascript,angular,rxjs,observable,chaining,Javascript,Angular,Rxjs,Observable,Chaining,我正在使用observable和flatMap操作符,我编写了一个方法,该方法进行API调用并返回一个带有对象数组的observable 基本上,我需要的是在处理完所有项目后,获取对象数组并处理每个对象。我想将结果链接起来,用我编写的另一个方法进行额外的API调用 以下代码满足我的需要: this.apiService.getInformation('api-query', null).first().flatMap((apiData) => { return apiData;

我正在使用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对象数组中的每个项执行一次。我知道我遗漏了什么或者误解了什么。但是从这个线程的第二个答案来看,我认为第二个flatMap应该返回已处理的apiData,而不是返回该数组上的每个对象项。我将非常感谢你的帮助


谢谢。

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

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);
  });

请参阅以获得进一步的澄清。

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

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);
  });
请参阅以获取进一步的说明。

您需要的是运算符,而不是
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
    有点多余)

    此外,如果要转换数据,则应使用而不是
    .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
    有点多余)

    此外,如果要转换数据,则应使用而不是
    .do()
    。我认为这就是你被.map()和
    .flatMap()
    搞混的地方