【问题标题】:TypeScript Convert Observable<Student[]>[] to Observable<Student[]>TypeScript 将 Observable<Student[]>[] 转换为 Observable<Student[]>
【发布时间】:2021-12-02 11:39:08
【问题描述】:

我正在尝试处理学生集合,并且对于每个学生调用不同的服务器 api,我该如何组合来自不同 api 的响应?

这里是问题的演示代码:

  test4(students:Student[]):Observable<Student[]> {
    var rr = students.map(student =>{
      if (student.age === 1) {
        return this.client
          .get('https://api.coindesk.com/v1/bpi/currentprice.json')
          .pipe(
            map((res) => {
              console.log(res);
              student.age = student.age * 100;
              return [student];
            })
          );
      } else {
        return this.client
          .get('https://api.coindesk.com/v1/bpi/currentprice.json')
          .pipe(
            map((res) => {
              console.log(res);
              student.age = student.age * 10000;
              return [student];
            })
          );
      }
    });
  }

如果可能,我不喜欢使用 forkjoin。

更新

我有这样的源数据

 getStudents(): Student[] {
    return [{ age: 1 }, { age: 2 }, { age: 3 }];
  }

如果年龄=1,则返回1100;如果年龄 >1 则返回 110000;在 *100 或 *10000 之前,它会向不同的 api 发送请求,我在上面的代码中模拟了 http 请求

函数的输入和输出将是test4(students: Student[]): Observable&lt;Student[]&gt;,这意味着最终结果将类似于of([{ age: 100 }, { age: 20000 }, { age: 30000 }])。 我还有另一个函数可以调用test4,如下所示:

  test() {
    this.test4(this.getStudents())
      .pipe(
        mergeMap((result) => {
          console.log(result);
          return of([]);
        })
      )
      .subscribe();
  }

它会记录类似[{ age: 100 }, { age: 20000 }, { age: 30000 }]

【问题讨论】:

    标签: angular typescript rxjs observable


    【解决方案1】:

    这是一种可能的解决方案,使用from 将数组转换为可观察流。 concatMap 将顺序执行 api,最后 toArray() 将所有输出分组到一个数组中。

    import './style.css';
    
    import { of, map, from } from 'rxjs';
    import { concatMap, toArray } from 'rxjs/operators';
    
    from([{ age: 1 }, { age: 4 }])
      .pipe(
        concatMap((student) => {
          return from(
            fetch('https://api.coindesk.com/v1/bpi/currentprice.json').then((res) =>
              res.json()
            )
          ).pipe(
            map((res) => {
              console.log(res);
              student.age = student.age * (student.age === 1 ? 100 : 10000);
              return student;
            })
          );
        }),
        toArray(),
      )
      .subscribe((output) => console.log(output));
    

    输出:

    [Object, Object]
    0: Object
    age: 100
    __proto__: Object
    1: Object
    age: 40000
    __proto__: Object
    

    stackblitz

    根据最新的输入,您需要修改结果并使用of 运算符返回以获得可观察的结果。

     getStudents(): Student[] {
        return [{ age: 1 }, { age: 2 }, { age: 3 }];
      }
    
    test4(inputArray: Array<Student>): Observable<Student[]> {
        return of(inputArray.map((student) => {
            student.age = student.age * (student.age === 1 ? 100 : 10000);
            return student;
        })
    }
    
     test() {
        this.test4(this.getStudents())
          .pipe(
            mergeMap((result) => {
              console.log(result);
              return of([]);
            })
          )
          .subscribe();
      }
    

    【讨论】:

    • 它是否将数组拆分为两个块?例如,我有[{ age: 1 }, { age: 2 },{ age: 4 }],对于[{ age: 1 },{ age: 2 }],请求api1,[{ age: 4 }],发送请求到api2,[{ age: 1 },{ age: 2 }]应该在一个请求中发送到api1,而不是循环这个数组来发送两个不同的请求。
    • 你分享的问题你想要 Observable 请根据我提供的示例显示代码的预期输出。
    • 我更新了原帖的输入输出,请帮忙检查
    • @Edward 已更新,如果要遍历数组中的每个元素,请使用我的第一个答案
    猜你喜欢
    • 2021-05-24
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 2018-10-23
    • 1970-01-01
    • 2016-04-19
    • 2021-10-27
    • 2023-03-23
    相关资源
    最近更新 更多