【问题标题】:RxJs map function causes upstream observable to be called multiple timesRxJs map 函数导致上游 observable 被多次调用
【发布时间】:2018-08-18 21:01:20
【问题描述】:

我对 RxJS 有点陌生,并且在 Observable 上遇到 map 问题,这会导致上游 Observable 被多次调用(即 HTTP 请求)。

我有以下例子:

https://stackblitz.com/edit/angular-rxjs-playground-uxygsb?file=app%2Fapp.component.ts

要点如下

function simulateHttp(val: any, delay:number) {
    return Observable.of(val)
        .delay(delay);
}

function timeLog(msg) {
    console.log(`${new Date().toISOString()}:  ${msg}`);   
}

const timerStream: Observable<number> = IntervalObservable
  .create(8000)
const manualRefreshStream = new Subject<any>();
const combinedTriggerStream: Observable<any> = Observable.merge(timerStream, manualRefreshStream);

const httpResultStream = combinedTriggerStream.switchMap(v => {
  return simulateHttp('http ' + v, 3000);
});
const dataStream = httpResultStream
  .map(v => `*${v}*`)
  .map(v => `#${v}#`);

基本上,只要我通过maphttpResult 流进行转换,我就会多次调用simulateHttp 方法。

我用谷歌搜索了一下,似乎share 可能是解决方案,但我不够精通,无法理解将它放在哪里以及为什么

【问题讨论】:

  • map 本身不会进行多次订阅,但您在示例中多次使用 logSubscribe 以至于很难判断订阅的来源。也许尝试使用do 记录您的流中发生的事情,您将避免多次订阅的副作用。
  • @martin,我在多次迭代中尝试了这个例子。只有当我在 httpResultStream 上执行map 时,问题才会开始。如果我不这样做,那么我只会得到一次调用。
  • @martin,感谢您提供的信息,我尝试删除 map 运算符确实表明根本原因是“冷”可观察的多个订阅者。连同来自@Jeto 的信息,我想我终于明白发生了什么。无论如何,我想我的主要困惑源于我的直觉是 switchMap 应该使 observable 变热,但它显然没有。

标签: javascript angular rxjs rxjs5


【解决方案1】:

我设法删除了多次调用

const httpResultStream = combinedTriggerStream
   .switchMap(v => simulateHttp('http ' + v, 3000))
   .share(); 

仍然不确定我为什么需要这个。

我还发现这篇文章很有帮助,尽管它与我的问题无关 https://blog.angular-university.io/rxjs-switchmap-operator/

【讨论】:

  • share 运算符使您的 observable “热”,这基本上意味着流在订阅者之间共享。网上有很多关于它的文章,例如this one
  • @Jeto 感谢您提供有趣的链接。我做了更多的挖掘,这似乎是由多个订阅者引起的。执行map 似乎没有任何区别,即使我可以发誓在添加 http 调用后我已经看到了多次调用。
猜你喜欢
  • 1970-01-01
  • 2013-05-05
  • 2023-03-04
  • 2022-08-19
  • 2017-02-12
  • 1970-01-01
  • 2017-06-14
  • 1970-01-01
  • 2017-05-04
相关资源
最近更新 更多