Angular 9: forkJoin 订阅无效

4

我正在尝试使用可观察对象(rxjs 6.5.1)在Angular 9的顶级组件上加载页面数据。当我单独订阅每个服务时,可以看到数据正常返回:

ngOnInit(): void {
  const technicianSubscription = this.techniciansClientService.getByTechnicianId(this.technicianId).subscribe(technician => console.log(technician));
  const technicianReviewsSubscription = this.technicianReviewsClientService.getByTechnicianId(this.technicianId).subscribe(technicianReviews => console.log(technicianReviews));
}

当我尝试使用forkJoin时,subscribe方法中的数据从未被返回:
ngOnInit(): void {
  this.pageDataSubscription = forkJoin({
    technician: this.techniciansClientService.getByTechnicianId(this.technicianId),
    technicianReviews: this.technicianReviewsClientService.getByTechnicianId(this.technicianId),
  }).subscribe(
    // data is never logged here
    data => console.log(data)
  );
}

我已经尝试使用forkJoin传递服务调用的数组,也尝试使用zip,但都没有成功。这里发生了什么?


奇怪..看起来它应该能正常工作 - Acebee
两个 getByTechnicianId 的调用都正常吗?请检查网络控制台。 - Pankaj Parkar
2
当其中一个或两个流发出事件但不完成时,您所描述的行为可以实现。forkJoin只在所有源都完成时才会发出事件。您能检查一下那个版本吗? - Andrei
@Andrei 我想这就是发生的事情。我尝试在forkJoin中放置不同的服务,它是成功的。因此,似乎技术人员服务调用没有完成。您是否建议像下面的答案那样使用combineLatest来解决我的问题? - EJ Morgan
1
这取决于您要处理的情况。您能提供技术服务返回的可观察对象吗?如果太复杂,我认为 ..getById(...).pipe(take(1)) 只从此可观察对象中获取一个事件将为您处理此问题。 - Andrei
1个回答

4

我建议使用rxjs中的combineLatest。它更容易使用。

import {combineLatest} from `rxjs`;

componentIsActive = true;
ngOnInit(): void {
  combineLatest([
    this.techniciansClientService.getByTechnicianId(this.technicianId),
    this.technicianReviewsClientService.getByTechnicianId(this.technicianId),
  ]).pipe(
    map(([technician, technicianReviews]) => ({technician, technicianReviews})),
    takeWhile(() => this.componentIsActive)
  ).subscribe(data => console.log(data));
}

3
这个有效!仍在查看文档以确定forkJoin出了什么问题... - EJ Morgan
这也证实了我在问题评论中提出的理论。你应该审视自己的情况并选择最佳选项。 - Andrei
1
还有一件对@Owen有用的事情 - takeWhile 取消订阅的方式比 takeUntil 更糟糕,因为它只会在事件通过此流时取消订阅。如果组件销毁后没有事件被发出,这可能会导致内存泄漏。而且,如果组件在响应下载之前被销毁,它也无法取消不必要的HTTP请求。 - Andrei
@Andrei 谢谢,我通常使用两者,大多数情况下使用 takeUntil,但现在我会坚持使用 takeUntil。 - Owen Kelvin
@EJMorgan,您在使用forkJoin时出现了类型错误,应该是forkJoin(this.techniciansClientService.getByTechnicianId(..),this.technicianReviewsClientService.getByTechnicianId(..)).subscribe(([technician, technicianReviews])=>{...}) - Eliseo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接