如何将Observable<Student[]>[]转换为Observable<Student[]>且不使用forkJoin
实现方案
核心代码修改(test4函数)
import { from, Observable } from 'rxjs'; import { map, mergeAll, toArray } from 'rxjs/operators'; test4(students: Student[]): Observable<Student[]> { const studentObservables = 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); return { ...student, age: student.age * 100 }; }) ); } else { return this.client .get('https://api.coindesk.com/v1/bpi/currentprice.json') .pipe( map((res) => { console.log(res); return { ...student, age: student.age * 10000 }; }) ); } }); // 无需forkJoin实现多请求合并 return from(studentObservables).pipe( mergeAll(), // 并发执行所有请求,若需要严格按输入顺序返回可替换为concatAll() toArray() // 所有请求完成后聚合为数组返回 ); }
调用代码优化
原有调用代码里的mergeMap属于冗余逻辑,直接在subscribe中接收结果即可:
test() { this.test4(this.getStudents()) .subscribe(result => { console.log(result); // 输出预期结果:[{ age: 100 }, { age: 20000 }, { age: 30000 }] }); }
实现说明
- 先将每个学生对象映射为对应的API请求Observable,请求完成后直接返回处理好age属性的学生对象,这里用对象扩展符返回新对象避免修改原始学生数据,也可以按需求直接修改原对象属性
from()将请求Observable数组转换为高阶Observable,逐个发出内部的请求ObservablemergeAll()会订阅所有内部请求,并发执行所有HTTP调用,每完成一个请求就发出对应的处理后学生对象toArray()会等待所有请求全部完成,把所有发出的学生对象聚合为一个数组,最终输出的类型完全符合Observable<Student[]>的要求
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

