首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >角:应该取消订阅从forkJoin管道由shareReplay(1)?

角:应该取消订阅从forkJoin管道由shareReplay(1)?
EN

Stack Overflow用户
提问于 2022-03-23 18:45:48
回答 2查看 353关注 0票数 0

我想知道是否有必要从使用运算符管道的一组HttpClient可观测到的用forkJoin([..])制作的可观测数据中取消订阅HttpClient?

我读过关于forkJoin(..)自动取消订阅的文章,但我不知道用shareReplay(..)运算符传递管道时是否是相同的情况,因为我读到这一次如果被误用会导致内存泄漏问题。

下面的示例用于缓存Http请求结果,下面是我的代码块:

服务:

代码语言:javascript
复制
@Injectable()
export class HttpcatcherService {
  codeNafsObservable$: Observable<any>;
  constructor(private positionservice: PositionserviceService) {}

  getAllEntities(refresh?: boolean): Observable<any> {
    if (!this.codeNafsObservable$ || refresh) {
      this.codeNafsObservable$ = forkJoin([
        this.positionservice.getPosts(), // returns Observable
        this.positionservice.getComments(), // returns Observable
      ]).pipe(
        map((result) => {
          return {
            secondNaf: result[0],
            thirdNaf: result[1],
          };
        }),
        shareReplay(1)
      );
    }
    return this.codeNafsObservable$;
  }
}

我的组件(知道我在不同组件中使用相同的方式/逻辑):

代码语言:javascript
复制
@Component({
  selector: 'hello',
  templateUrl: './hello.component.html',
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent implements OnInit {
  constructor(private httpCat: HttpcatcherService) {}
  ngOnInit(): void {
    this.httpCat
    .getAllEntities()
    .subscribe(
     (result) => {
      console.log(result);
    });
  }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-03-23 20:34:04

我认为使用forkJoinshareReplay不会导致任何内存泄漏问题。原因如下:

  • 当所有可观测数据以参数forkJoin的形式传入时,complete会发出通知。在这种情况下,由于传递给forkJoin的可观察到的调用与http调用相关,所以它们在http调用返回后就完成了。因此,当两个http调用都返回时,forkJoin创建的可观察到的消息就会通知并完成。
  • shareReplay的作用是创建一个内部缓存,确保任何订阅都将得到上游通知的最后一个值。在这种情况下,上游通知的最后一个值是forkJoin创建的可观察值所通知的唯一值。

当可观察到的源是无限流(例如用shareRepley创建的流)时,内存泄漏的风险,或者至少是使用interval不受控制地执行代码的风险。在这种情况下,shareReplay创建了一个可观察的、从未完成的可观察性,即使没有订阅服务器,除非ShareReplayConfigrefCount属性设置为true

这个行为在详细的在文件中中得到了解释。

在任何情况下,这都不是您运行的风险,因为您所拥有的源只会发出一次,然后完成。

票数 4
EN

Stack Overflow用户

发布于 2022-03-23 20:37:25

在RxJS 7中,shareReplay(1)是一个包含以下参数的共享包装器:

代码语言:javascript
复制
  share({
    connector: () => new ReplaySubject(1),
    resetOnComplete: false,
    resetOnError: false,
    resetOnRefCountZero: false
  })

如果您希望更好地控制shareReplay的工作方式,请使用share,并根据需要设置配置选项。

例如,如果将resetOnRefCountZero设置为true,则当不再有任何订阅者时,内部ReplaySubject将被取消订阅。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71592457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档