在http调用的情况下Angular 2订阅/取消订阅Observables

问题描述:

我最近才知道,在Angular销毁组件之前,我们必须取消订阅,否则这样做可能会导致内存泄漏.

I recently came to know that we must unsubscribe the subscription before Angular destroys the component, and failure to do so could create a memory leak.

我还知道我们可以获取对该订阅的引用,并且可以通过对该订阅调用unsubscribe方法来进行订阅.例如

I also know that we can get a reference to the subscription and by calling unsubscribe method on that subscription we can subscribe. For example

private sub: any;

ngOnInit() {
  this.sub = this.route.params.subscribe(params => {
     let id = +params['id']; // (+) converts string 'id' to a number
     this.service.getHero(id).then(hero => this.hero = hero);
   });
}


ngOnDestroy() {
  this.sub.unsubscribe();
}

在HTTP调用中也有必要吗? 如果是,那么在这种情况下的最佳做法是什么.

Is this necessary in the case of HTTP calls as well? If yes, then what's the best practice in this case.

例如,我们通常有类似的东西可以通过HTTP发布一些数据

For example, we usually have something like this to post some data through HTTP

let body = JSON.stringify({ name });
let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({ headers: headers });

this.http.post(this.heroesUrl, body, options)
                .map(this.extractData)
                .subscribe((data) => {
                 //do something with data
                })
                .catch(this.handleError);

下面的方法是否可行?在HTTP调用的情况下,这是退订的最佳方法吗?

Will the below work, and is it the best way to unsubscribe in the case of HTTP calls?

private sub: any;

.....
....

this.sub = this.http.post(this.heroesUrl, body, options)
                .map(this.extractData)
                .subscribe((data) => {
                 //do something with data
                 this.sub.unsubscribe();
                })
                .catch(this.handleError);

否,没有必要取消订阅.简而言之,NG2将自动清除,如此处:

No, it is not necessary to unsubscribe. In short, NG2 will clean up after itself as seen here:

    if (response.ok) {
      responseObserver.next(response);
      // TODO(gdi2290): defer complete if array buffer until done
      responseObserver.complete();
      return;
    }
    responseObserver.error(response);
  };