[英]RxJS Node wait for observable to complete before subscribing to the next in sequence
[英]RxJS: Modify Observable array before subscribing
我正在从返回 Observable 的 API 中获取数据( students
通过getStudents()
)。 在这个结果中,我需要从两个不同的表中获取数据并组合结果。
这是我的简化界面:
export interface student Student {
id: string
name: string,
school_id: string,
classroom_id: string
}
export interface school School {
id: string,
name: string
}
export interface classroom Classroom {
id: string,
name: string
}
我现在需要获取所有students
,并通过外键school_id
和classroom_id
ID 为每个student
添加各自的school
和classroom
。
我目前的方法如下所示。 我知道它尚未完成,但我无法找到合适的操作员以及如何正确使用它。
this.getStudents().pipe(
switchMap(students => {
student.map(student => forkJoin([
this.getSchool(student.school_id),
this.getClassroom(student.classroom_id)
]))
})
)
所有方法( getStudents()
、 getSchool()
、 getClassroom()
)都返回 Observables。 我的目标是在订阅后让一系列students
拥有各自的school
和classroom
数据。
如果我需要获取单个学生(例如使用getStudent()
)然后使用combineLatest
组合多个流,我知道如何完成它。 但是当获取多个students
时,情况就不同了。
先感谢您!
您需要forkJoin
从student.map()
获得的可观察数组,并使用map
将结果投影到所需的 object 中。
const result$ = getStudents().pipe(
switchMap((students: Student[]) =>
forkJoin(students.map(student =>
forkJoin([
getSchool(student.school_id),
getClassroom(student.classroom_id)
]).pipe(map(([school, classroom]) => ({
student,
school,
classroom
}))
)
))
));
您可以做的是将原始数组结果转换为 stream 发射每个学生并一一构造每个记录。 构建 object 后,您可以使用toArray()将其返回到单个数组结果。 我发现以这种方式做事(将发出 arrays 的 stream 展平到发出单个元素的 stream 中)由于减少了嵌套而更易于管理。
this.getStudents().pipe(
switchMap(students => students), // emit each element individually
concatMap(student => // construct the student object.
forkJoin({
classRoom: this.getClassroom(student.classroom_id),
school: this.getSchool(student.school_id),
student: of(student)
})
),
toArray() // when all results are built, emit one array result.
);
如果getStudents()返回单个发射然后完成,则此技术效果最佳。 如果 observable 保持打开状态,则toArray()将不会发出,因为它仅在源 observable 完成时执行。
如果它确实保持打开状态,但您只想要第一个阵列发射,那么在 pipe 的开头添加take(1)或first()就可以了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.