javascript - 为什么在没有 shareReplay() 的情况下对可观察对象的两次订阅不会执行代码两次?

标签 javascript angular typescript rxjs observable

我试图找出 RxJ。尤其是 ShareReplay 运算符。根据我的理解,如果一个可观察对象有两个订阅,那么该可观察对象应该执行两次。除非涉及到shareReplay。显然我的理解是不正确的,因为这不是我在这里发生的事情。有人可以帮我理解这一点吗?

export class TestComponent implements OnInit {
      constructor() {}
      i = 0;
      ngOnInit() {
        console.clear();
        let ob = this.httpcall().pipe(map(d => d));
        let ob1$ = ob.pipe(map(d => d.toUpperCase()));
        let ob2$ = ob.pipe(map(d => d.toLowerCase()));

        ob1$.subscribe(d => {
          console.log(d);
        });
        ob2$.subscribe(d => {
          console.log(d);
        });
      }

      httpcall() {
        console.log("called");
        this.i++;
        return of("server cAlled:" + this.i);
      }
    }

输出:

called
 SERVER CALLED:1
 server called:1

即使有两个订阅并且不涉及 shareReplay,计数器 i 也没有增加到 2。

我期待着(没有 shareReplay):

 called
 SERVER CALLED:1
 called
 server called:2

使用 let ob = this.httpcall().pipe(map(d=>d),shareReplay()); 我期待:

 called
 SERVER CALLED:1
 server called:1

最佳答案

当你调用 subscribe 时,这将导致 observable 执行它定义的所有操作。它是使用 of("server cAlled: 1"); 定义的,然后传递给映射运算符。因此,由于您订阅了两次,of 会执行两次操作,map 也会执行两次操作。

您碰巧在名为 httpcall 的函数内创建了可观察对象,但该可观察对象对 httpcall 一无所知。 httpcall 不会被再次调用。

如果您希望 this.i 的递增成为订阅时发生的事情的一部分,那么您可能需要使用 Observable.create。例如:

httpcall() {
  return Observable.create((observer) => {
    this.i++;
    observer.next("server called: " + this.i);
    observer.complete();
  })
}

关于javascript - 为什么在没有 shareReplay() 的情况下对可观察对象的两次订阅不会执行代码两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56976806/

相关文章:

javascript - Angular2 中的泳道 ngx-图表 - 单个折线图上的不同样式

TypeScript 泛型 : what if Promise reject and resolve types differ?

typescript - 正确输入具有绑定(bind)运行功能的 map

javascript - TypeScript requirejs 加载外部模块的问题

javascript - 动态访问Javascript数组

Angular 6 Safari 路由器相关错误

javascript - 如果选择日期,隐藏图标

html - 错误 : Cannot change `multiple` mode of select after initialization

javascript - Nuxtjs插件注册

javascript - 无论 Firefox 中的布局区域如何,工具提示都会在同一位置打开