Angular中map操作内等待Observable HttpClient执行完成的问题
问题原因
你代码的核心问题是在mergeMap回调中直接对HttpClient.get()返回的Observable进行了subscribe,这部分异步请求会独立于当前流执行,不会阻塞后续return of(result)的逻辑,所以会先执行到外层的console.log(result[0]),等http请求响应回来才会执行console.log(res)。
修正方案
我们需要把每个学生的处理逻辑都封装成Observable,用forkJoin等待所有异步操作完成后再将处理后的结果向下游传递,修改后的代码如下:
import { forkJoin } from 'rxjs'; // 未导入forkJoin时需要先添加该导入语句 test() { this.test2() .pipe( mergeMap((result) => { console.log(result[0]); return of([]); }) ) .subscribe(); } test1(): Observable<Student[]> { return of(this.getStudents()); } test2(): Observable<Student[]> { return this.test1().pipe( mergeMap((result: Student[]) => { if (!result) return of([]); // 将每个学生的处理逻辑转换为对应的Observable const handleTasks = result.map(rr => { if (rr.age === 1) { return this.client.get('https://api.coindesk.com/v1/bpi/currentprice.json').pipe( map(res => { console.log(res); rr.age = rr.age * 10000; return rr; }) ) } else { rr.age = rr.age * 10; return of(rr); } }) // 等待所有处理任务(含异步请求)全部完成后再返回最终数组 return forkJoin(handleTasks); }) ); } getStudents(): Student[] { return [{ age: 1 }, { age: 2 }, { age: 3 }]; }
核心改动点
- 移除了对
HttpClient.get()的直接subscribe调用,改为将请求流返回,交由RxJS操作符统一管理执行时机 - 将每一个Student对象的处理逻辑都转换为对应的Observable:符合条件的学生返回http请求流,请求完成后修改age再返回学生对象;不符合条件的直接返回同步处理后的学生对象流
- 使用
forkJoin组合所有学生的处理流,等待所有流(包括异步http请求)全部完成后,再将最终处理完成的学生数组向下游传递,保证下游拿到结果时所有异步修改已经执行完毕
内容的提问来源于stack exchange,提问作者Edward
相关产品推荐
相关产品推荐

