订阅中的角度订阅

时间:2019-04-01 03:35:28

标签: angular rxjs

我有以下包含多个订阅的代码。我需要实现的是这样的:

  1. 订阅activatedRoute以获取用户和产品数据。
  2. 返回产品数据后,使用产品数据订阅getSeller服务。
  3. 使用返回的卖家数据订阅getRating服务。

我的问题:是否有更好的方法来执行这些嵌套订阅?这样做是一种好习惯吗?

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;
      })

    });
  }
});

3 个答案:

答案 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()