【问题标题】:订阅一组 HTTP 可观察对象
【发布时间】:2022-01-23 15:36:52
【问题描述】:

我有一个包含在activatedRoute.data.example 中的Observable 数组,我想订阅发出的最新值。

private data$ = forkJoin(
  this.activatedRoute.data.pipe(
    map(({ examples }) => examples)
  )
);

ngOnInit(): void {
  this.data$.subscribe((v) => console.log(v));
}

这里的每一个example都是一个http请求:

this.http.get<Example>(`${this.baseUrl}`, { params: query })

但我在网络浏览器的选项卡中既没有看到log,也没有看到对后端的 API 调用。

【问题讨论】:

  • ForkJoin 在您的情况下不起作用,它正在发出值,当所有传递的 observables 都将完成时。只需将其删除并重试。
  • 非常感谢。如果你有时间,还有一个问题:有没有一种方法可以确定是否所有的 observables 都完成了?
  • 当你订阅一个 observable 时,有 3 个参数函数。 nexterrorcomplete。调用complete函数就知道订阅完成了。
  • 请注意,当 HTTP 调用完成时,HTTP 客户端会自动完成订阅,这通常不会发生在其他可观察对象(路由器事件、存储订阅等)中
  • @StPaulis 这是冷热观测值的区别。

标签: angular rxjs


【解决方案1】:

map 是一个选项,使用带有 from rxjs 运算符的 switchMap 更清晰的方法(您也可以寻找 concatMap 和 mergeMap) .所以在实现中,你基本上可以做到:

  this.activatedRoute.data.pipe(
    map(({ examples }) => from(examples)),
    concatMap((examples) => examples)
  ).subscribe(...);

如果这没有帮助,我附上Stackblitz link

【讨论】:

  • 这不是一个真正的解决方案,它在你的 stackBlitz 中有效,因为你正在使用 of(),它会在那里返回响应,但在真正的 API 中有一个旅行延迟,如果你在您的示例中添加延迟,只有最后一个响应才会得到响应。
  • 这是一个模拟解决方案。我认为现实世界的应用程序不会有什么不同。 of() 在那里创建 observable,但它不会改变代码逻辑,我们在 pipe() 上运行我们的代码逻辑。它与何时创建 observable 无关。我为你重新安排了这个例子。我添加了一个模拟延迟,它仍然有效:stackblitz.com/edit/angular-ivy-rv8bho?file=src/app/…
  • 而且,在那一刻,他拥有可观察的数组。
  • “这里的每个例子都是一个http请求”,意思是例子是一个API Observable,你把delay放在了错误的地方,试试这个[of(1).pipe(delay(1)), of(2)]你会明白我的意思。跨度>
  • 是的,在这种情况下你是对的,只要这些 observables 完成,switchMap 就会立即返回。我以为他需要这个。但如果没有,使用 concatMap 而不是 switchMap 将解决问题。见链接:stackblitz.com/edit/angular-ivy-bdzwxh?file=src/app/…
【解决方案2】:

rxjs 的map 与 Array 的 'map' 不同。

显示它应该实际工作的粗略示例:

private data$: Observable;

ngOnInit(): void {

  let getExample = (query) => this.http.get < Example > (`${this.baseUrl}`, {
    params: query
  });

  this.activatedRoute.data.subscribe(({ examples}) => { // if example is array 

    let obsArray: Observable[] = Object.entries(examples).map(([key, value] => getExample({
        [key]: value
      }));
      
      data$ = forkJoin(obsArray); 
      data$.subscribe(); // if needed
    });

}

【讨论】:

    【解决方案3】:

    我解决了直接从解析器返回Observables 的forkJoin(),而不是通过ReplaySubject 订阅Observable

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-28
      • 1970-01-01
      相关资源
      最近更新 更多