Машинописный текст Преобразует Наблюдаемый[] в наблюдаемый

#angular #typescript #rxjs #observable

Вопрос:

Я пытаюсь обработать коллекцию учащихся, и для каждого учащегося вызывается другой серверный 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, то верните 1 100; Если возраст >1, то верните 1>10000; до *100 или *10000 он отправит запрос в другой api, я высмеял http-запрос в приведенном выше коде

Ввод и вывод для функции будут test4(students: Student[]): Observable<Student[]> такими, что означает, что конечный результат будет примерно таким 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 }]

Ответ №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
 

стакблитц

На основе последних входных данных вам необходимо изменить результаты и вернуться с 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();
  }
 

Комментарии:

1. Это разбиение массива на два блока? например, у меня есть [{ age: 1 }, { age: 2 },{ age: 4 }] , например [{ age: 1 },{ age: 2 }] , запрос api1, [{ age: 4 }] , отправить запрос на api2, и [{ age: 1 },{ age: 2 }] его следует отправить на api1 в рамках одного запроса вместо того, чтобы зацикливать этот массив для отправки двух разных запросов.

2. в вопросе, которым вы поделились, вы хотите, чтобы наблюдаемый<Студент []>, пожалуйста, покажите ожидаемый результат кода на основе приведенного мной примера.

3. Я обновляю ввод и вывод в исходном сообщении, пожалуйста, помогите проверить

4. @Edward обновлено, если вы хотите повторить каждый элемент в массиве, используйте мой первый ответ