![](/img/trans.png)
[英]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.