【问题标题】:Angular 9: forkJoin subscribe not workingAngular 9:forkJoin 订阅不起作用
【发布时间】:2020-09-05 15:53:07
【问题描述】:

我正在尝试使用 observables (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 时,订阅方法中的数据永远不会返回:

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,但无济于事。这里发生了什么?

【问题讨论】:

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

标签: javascript angular rxjs observable angular9


【解决方案1】:

我建议使用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));
}

【讨论】:

  • 这成功了!仍在挖掘文档以查看 forkJoin 出了什么问题...
  • 这也证实了我在问题评论中提出的理论。您应该检查您的情况并选择最佳选择
  • 这对@Owen 也很有用 - takeWhile 取消订阅的方式比 takeUntill 更糟糕,因为它只会在事件通过此流时取消订阅。如果在组件被销毁后没有发出任何事件,这可能会导致内存泄漏。如果组件在响应下载之前被销毁,它也不会取消不需要的 http 请求
  • @Andrei 谢谢,我通常都使用,主要是 takeUntil,但现在我会坚持 takeUntil
  • @EJMorgan,您使用 forkJoin 时出现类型错误,是 forkJoin(this.techniciansClientService.getByTechnicianId(..),this.technicianReviewsClientService.getByTechnicianId(..).subscribe(([technician, technicianReviews])=>{...})
猜你喜欢
  • 2021-03-02
  • 2021-04-24
  • 2020-10-11
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
  • 2020-03-29
  • 1970-01-01
  • 2023-03-22
相关资源
最近更新 更多