首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何防止此angular6 rxjs 6的泄漏

如何防止此angular6 rxjs 6的泄漏
EN

Stack Overflow用户
提问于 2018-06-07 21:30:50
回答 2查看 148关注 0票数 1

我的authService.ts中有以下函数

它起作用了,但是订阅泄露了。它在几乎每个组件上的整个应用程序中都被使用。

代码语言:javascript
复制
   mouseEvents:  Subscription;
    timer: Subscription;

    constructor() {
      if(user){
        this.updateOnIdle(user.uid);
      }
    }

private updateOnIdle(userId) {
  this.mouseEvents =  fromEvent(document, 'mousemove')
                       .pipe(
                        throttleTime(2000)
                      )
                      .subscribe(() => {
                        firebase.database().ref('/status/' + userId).set({
                          status: 'online',
                          last_changed: firebase.database.ServerValue.TIMESTAMP
                      });
                        this.resetTimer(userId)
                     });
}

/// Reset the timer
private resetTimer(userId) {
  if (this.timer) {this.timer.unsubscribe()}

  this.timer = timer(5000)
                  .map(() => {
                    firebase.database().ref('/status/' + userId).set({
                      status: 'away',
                      last_changed: firebase.database.ServerValue.TIMESTAMP
                  });
                  }).subscribe();
}

我该如何解决这个问题?编写函数的更好方法是什么?

EN

回答 2

Stack Overflow用户

发布于 2018-06-07 21:47:35

泄漏问题的一个解决方案是不在ts中使用订阅,而是返回可观察数据,并让angular的async管道为您管理订阅。

代码语言:javascript
复制
mouseEvents$:  Observable<any>;
timer$: Observable<any>;

constructor() {
  if(user){
    this.updateOnIdle(user.uid);
  }
}

private updateOnIdle(userId) {
  this.timer$ =  fromEvent(document, 'mousemove')
                       .pipe(
                        throttleTime(2000),
                        switchMap(() => firebase.database().ref(`/status/${userId}`).set({status: 'online', last_changes: firebase.database.ServerValue.TIMESTAMP}),
                        map(your reset timer logic here)
                      );
                        this.resetTimer(userId);
                     });
}

然后在您使用它的html中。

代码语言:javascript
复制
<div class="myTimer" [time]="timer$ | async"></div>
票数 2
EN

Stack Overflow用户

发布于 2018-06-08 05:36:13

我只是在回答了你后来提出的问题here之后才看到这个问题。我现在可以看到更大的图景,以及为什么在另一个问题中没有subscribe()调用。

本质上,我认为你所谓的“泄漏”是指在使用该服务的组件被销毁后,鼠标事件会继续触发?

如果是这样,那么处理它的方法可能是计数服务内部的引用,并在最后一个停止时执行unsubscribe()。像这样,

代码语言:javascript
复制
@Injectable()
export class MyService {

  mouseEvents:  Subscription;
  timer: Subscription;
  refs = 0;

  constructor() {
  }

  public start() {
    if (!refs) {
      this.updateOnIdle(user.uid);
    }
    refs += 1;
  }

  public stop() {
    refs -= 1;
    if (!refs) {
      mouseEvents.unsubscribe();
      timer.unsubscribe();
    }
  }

  private updateOnIdle(userId) {
    ...
  }

在组件中,

代码语言:javascript
复制
@Component()
export class MyComponent implements OnInit, OnDestroy {

  constructor(
    private myService: MyService
  ) {}

  ngOnInit() {
    myService.start();
  }

  ngOnDestroy() {
    myService.stop();
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50742564

复制
相关文章

相似问题

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