#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 обновлено, если вы хотите повторить каждый элемент в массиве, используйте мой первый ответ