RxJS使用concatAll处理流时输出Observable未订阅执行的问题
问题原因
你的代码输出Observable对象的核心原因是流的打平层级不够:
getCourses()返回类型为Observable<Course[]>,只会发射1个值:完整的课程数组- 经过第一层
map转换后,流变成Observable<Observable<Assignment>[]>,发射的值是装满getAssignments返回的Observable对象的数组 - 第一层
concatAll只会把外层Observable发射的数组拆成单个元素(即每个未订阅的Observable对象)发射,不会自动订阅这些内部Observable,因此你最终拿到的就是Observable实例而非接口返回的作业数据。
解决方案
方案1(更推荐,逻辑更清晰)
先把课程数组拆为单个课程对象逐个发射,再用concatMap直接映射为作业请求,自动完成内部Observable的订阅和打平:
const assignments = getCourses() .pipe( // 把课程数组拆为单个课程对象逐个发射 concatMap(courses => from(courses)), // 每个课程调用作业接口,自动订阅内部Observable按顺序返回结果 concatMap(course => getAssignments(course.id)) ) assignments.pipe(tap(r => console.log(r))).subscribe();
如果不需要严格按照课程顺序返回作业数据,可以把concatMap替换为mergeMap提升请求并发效率。
方案2(直接修改原有代码)
在原有逻辑基础上再加一层concatAll,订阅第一层concatAll发射的所有内部Observable:
const assignments = getCourses() .pipe( map((response) => response.map((r: any) => getAssignments(r.id))), concatAll(), // 拆分Observable数组为单个Observable逐个发射 concatAll() // 订阅每个Observable,返回接口响应的作业数据 ) assignments.pipe(tap(r => console.log(r))).subscribe();
内容的提问来源于stack exchange,提问作者richbai90
相关产品推荐
相关产品推荐

