我有以下包含多个订阅的代码。我需要实现的是这样的:
我的问题:是否有更好的方法来执行这些嵌套订阅?这样做是一种好习惯吗?
this.activatedRoute.data.pipe(
map((data) => {
this.user = data['user'];
this.product = data['product'];
return this.product;
})
).subscribe(result => {
if (this.product === null) {
this.router.navigate(['/home']);
} else {
this.displayCurrency = this.dataService.getCurrencySymbolById(this.product.currency);
this.userService.getUser(this.product.createdBy).subscribe(seller => {
this.seller = seller;
this.ratingService.getRatingByUserId(seller.id).subscribe(rating => {
this.rating = rating;
})
});
}
});
答案 0 :(得分:3)
从技术上讲,嵌套订阅工作,但是有一种更优雅,系统的方式来处理此问题。您应该真正了解有关RxJS运算符的更多信息。
首先,我们使用mergeMap来将ActivatedRoute的可观察值映射到内部可观察值。
然后,我们使用forkJoin将可观察值组合成单个可观察值,从而在.subscribe()
上返回值本身
this.activatedRoute.pipe(
tap(data => console.log(data)),
mergeMap(data => {
if (data.product === null) {
this.router.navigate(['/home']);
} else {
const getCurrency = this.dataService.getCurrencySymbolById(data.product.currency);
const getUsers= this.userService.getUser(data.product.createdBy);
const getRatings = this.ratingService.getRatingByUserId(seller.id)
return forkJoin(getCurrency, getUsers, getRatings);
}
})
).subscribe(res => {
console.log(res[0]); // currency
console.log(res[1]); // user
console.log(res[2]); // ratings
}
编辑:原来我误解了原来的问题,因为getRatingsByUserId依赖于getUser。让我做些改变。无论哪种方式,我都会保留上面的代码,因为这对OP很有用。
this.activatedRoute.data.pipe(
switchMap(data => {
this.user = data['user'];
this.product = data['product'];
return this.userService.getUser(this.product.createdBy);
}),
switchMap(data => {
if (this.product === null) {
this.router.navigate(['/home']);
} else {
this.seller = seller;
return this.userService.getRatingByUserId(this.product.createdBy);
}
})
).subscribe(res => {
console.log(res)
// handle the rest
})
答案 1 :(得分:0)
使用switchMap切换到新的可观察对象。
this.activatedRoute.data.switchMap((routeData) => {
this.user = routeData['user'];
this.product = routeData['product'];
return this.userService.getUser(this.product.createdBy);
}).switchMap(seller => {
this.seller = seller;
return this.ratingService.getRatingByUserId(seller.id);
}).subscribe(rating => {
this.rating = rating;
})
答案 2 :(得分:0)
您可以使用 mergeMap
.serializeArray()