取消订阅角度服务

时间:2019-12-18 19:08:13

标签: angular

我试图了解调用角度服务时使用ngDestroy或退订的最佳实践。通过下面的示例,有人可以告诉我在这种情况下如何正确使用ngDestroy吗?

this.submitPostService.getUserName(this.userId).subscribe(user => {
  console.log("THIS IS THE USER!");
  console.log(user);
  this.username = user.posts.name;
  console.log(this.username);
});

角度服务

  getUserName(id: string) {
    return this.http.get<{ posts: any }>(
      `http://localhost:3000/api/user/${id}?username=` + id
    );
  }

3 个答案:

答案 0 :(得分:1)

看下面的例子。这样,我可以确保在销毁组件时总是发生取消订阅的情况。

import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
//...

export class AppComponent implements OnInit, OnDestroy {
  private destroyed$ = new Subject();
  //...

  ngOnInit() {
    this.submitPostService.getUserName(this.userId)
      .pipe(takeUntil(this.destroyed$))
      .subscribe(user => {
        console.log(user);
    });
  }

  ngOnDestroy() {
    this.destroyed$.next();
    this.destroyed$.complete();
  }
}

此处的关键元素是destroyed$takeUntil一个rxjs运算符。在您的服务电话中,您可以使用.pipe(takeUntil(this.destroyed$)来简单地说,订阅直到destroyed $为真。您可以在所有组件订阅中使用它。

希望此帮助(: 您可以查看this article了解更多信息。

答案 1 :(得分:0)

您必须首先将可观察对象保存在类级变量中

this.subscription = this.submitListingService.getUserName(this.userId).subscribe(...

然后在组件销毁方法或其他方法中,可以将方法取消订阅

this.subscription.unsuscribe();

答案 2 :(得分:0)

以您的示例为例,http.get是一个自我完成的方法,这意味着您不需要按组件本身退订。 您可以查看类似的问题:Is it necessary to unsubscribe from observables created by Http methods?

我想以下模板足以满足仅视图逻辑组件的需求:

export class AppComponent implements OnInit, OnDestroy {
    renderTimeSubs: Subscription[] = [];
    keepUpdateSub1: Subscription = null;
    constructor(private aService: AService) {}

    ngOnInit() {
      this.renderTimeSubs = [];
      this.aService.selfClosedObs.subscribe();// you don't need to handle the self-completed subscription
      const sub1 = this.aService.nonSelfClosedObs().subscribe();
      this.renderTimeSubs.push(sub1);
    }
    updateSubscription() { /** handle in service is a better manner */
        if (this.keepUpdateSub1 && !this.keepUpdateSub1.closed) {
            this.keepUpdateSub1.unsubscribe();/** close Observable between Init&Destroy component*/
        }
        this.keepUpdateSub1 = aService.getANewNonClosedObservable;/** new non-closed Observable*/
    }
    ngOnDestroy() {
      this.renderTimeSubs .forEach(x => x.unsubscribe());
      if (this.keepUpdateSub1 && !this.keepUpdateSub1.closed) {
        this.keepUpdateSub1.unsubscribe();
      }
    }
}