![](/img/trans.png)
[英]Is there a way to subscribe to a room's `participantConnected` event without becoming a participant?
[英]Is there any way to avoid nested subscribe?
( https://i.stack.imgur.com/2zm2w.png )
collectionData(queryRef).subscribe((data) => {
for (const each of data) {
this.getCourse(each.courseId)
.pipe(take(1))
.subscribe((courseData) => {
const course = courseData[0];
console.log(course);
this.getLecturer(course.lecturerId).pipe(take(1)).subscribe((res: any)=>{
const lecturer = res[0];
course.lecturerName = lecturer.lecturerName;
course.lecturerImageUrl = lecturer.lecturerImageUrl;
});
recentVisit.push(course);
});
}
});
嗨,我還是 Angular 的 rxjs 的新手。我正在使用 Angular Fire 構建一個 Ionic 應用程序。 我目前在這里遇到一些問題,我使用 Firebase 作為我的后端,我將不得不通過不同的 collections 查詢來獲取我的數據。 例如,第一個訂閱只獲取用戶課程注冊數據,如 courseId、progress...,第二個訂閱將獲取課程詳細信息,第三個訂閱將獲取講師詳細信息。 任何人都可以就如何避免使用嵌套訂閱提出一些建議,因為很多人說不建議這樣做。 如果你能提供一些詳細的解釋,我將不勝感激,因為我真的只知道 rxjs 的基礎知識。
我試過 concatMap 但它顯示 firebase 錯誤( https://i.stack.imgur.com/6SOS0.png )]
collectionData(queryRef)
.pipe(
concatMap((res: any) => this.getCourse(res.courseId))
//concatMap((result2: any) => this.getLecturer(result2.lecturerId))
)
.subscribe((res) => {
console.log(res);
});
但實際上我也不確定我是否做對了,因為我真的不明白 concatMap 是如何工作的。
我創建了一個解決方案,通過執行以下操作來防止嵌套管道以及多個顯式訂閱:
switchMap
和forkJoin
getMergedCourseDetails()
以保持主要 pipe 平坦/* Initialize all information about the courses */
ngOnInit(): void {
this.collectionData(this.queryRef).pipe(
switchMap(data => {
if (data.length) {
// Create an observable (backend-request) for each course-id:
const courseObs = data.map(c => this.getCourse(c.courseId));
// Execute the array of backend-requests via forkJoin():
return courseObs.length ? forkJoin(courseObs) : of([]);
}
return of([]);
}),
switchMap((courseDataList: Course[][]) => {
if (courseDataList.length) {
// Get the first course from each course array (as defined in SO question):
const courses = courseDataList.filter(c => c.length).map(c => c[0]);
// Create observables to retrieve additional details for each of the courses:
const detailInfoObs = courses.map(c => this.getMergedCourseDetails(c));
// Execute the created observables via forkJoin():
return detailInfoObs.length ? forkJoin(detailInfoObs) : of([]);
}
return of([]);
}),
tap((courseList: Course[]) => {
courseList.forEach(d => {
console.log('Lecturer Id:', d.lecturerId);
console.log('Lecturer Name:', d.lecturerName);
console.log('Lecturer ImageUrl:', d.lecturerImageUrl);
});
})
)
.subscribe();
}
/* Enrich existing course-data with lecturer-details */
private getMergedCourseDetails(course: Course): Observable<Course> {
return this.getLecturer(course.lecturerId).pipe(
map(lecturers =>
// Merge existing course-data with newly retrieved lecturer-details:
({...course,
lecturerName: lecturers[0]?.lecturerName ?? '',
lecturerImageUrl: lecturers[0]?.lecturerImageUrl ?? '' } as Course))
);
}
如果您使用嵌套訂閱,則意味着它將等待第一個返回值,然后調用第二個,依此類推。 這會花費很多時間。 您可以在此使用的是 forkJoin():
forkJoin(
{
a: this.http.call1()..
b: this.http.call2()..
c: this.http.call3()..
}).subscribe()
forkJoins 等待所有 3 個 Observables 發出一次並為您提供所有值。 這里的例子: https://www.learnrxjs.io/learn-rxjs/operators/combination/forkjoin
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.