Angular2: Отказаться от http, наблюдаемого в службе

Какова наилучшая практика отмены подписки в службе Angular2 из подписки на http?

В настоящее время я делаю это, но я не уверен, что это будет лучший способ.

import { Injectable } from "@angular/core";
import { Http } from "@angular/http";

import { Subject } from "rxjs/Subject";
import { ISubscription } from "rxjs/Subscription";

@Injectable()
export class SearchService {
    private _searchSource = new Subject<any>();

    public search$ = this._searchSource.asObservable();

    constructor(private _http: Http) {}

    public search(value: string) {
        let sub: ISubscription = this._http.get("/api/search?value=" + value)
            .map(response => <any>response.json())
            .do(data => this._searchSource.next(data))
            .finally(() => sub.unsubscribe()).subscribe();
    }

}

Ответ 1

Служба в Angular является одноэлементной. Это означает, что служба будет существовать на протяжении всего срока действия вашего приложения.

Причина, по которой вам нужно отменить подписку на наблюдаемое, заключается в том, чтобы избежать утечек памяти. Когда вы получаете утечки памяти? Если что-то было собрано в мусор, пока оно все еще подписано на наблюдаемого, прослушивателя событий, сокета,...

Так как служба Angular никогда не уничтожается, если только ваше приложение не уничтожено, нет никакой реальной причины отказаться от него. Наблюдаемый будет либо завершен, либо будет ошибкой или продолжит работу до тех пор, пока ваша заявка будет выполнена.

Заключение: Отмена подписки на услугу является бессмысленной, поскольку нет возможности утечки памяти.

Ответ 2

Вам не нужно отписываться от наблюдаемой, созданной Http или HttpClient потому что она конечно наблюдаема (значение будет HttpClient только один раз, и будет HttpClient complete).

Однако вы МОЖЕТЕ отменить HttpClient на HttpClient созданную HttpClient чтобы отменить запрос. Это означает, что вас больше не интересуют данные, возвращаемые запросом.

Ответ 3

Я не согласен с KwintenP ответом. Да, в случае наблюдения за вызовом HttpClient нет необходимости отписываться, как Владимир правильно упомянул, однако в других заметках вам может понадобиться отказаться от подписки в службе.

Давайте рассмотрим простой пример: предположим, у нас есть хранилище, которое отправляет наблюдаемые, а в хранилище у нас есть наблюдаемая clicker, которая запускает true всякий раз, когда щелкают правой кнопкой мыши (по какой-то странной причине) И предположим, что у нас есть MyWeirdService, который делает следующее:

class MyWeirdService {
  doSomethingUnthinkableManyTimes() {
    this.store.select('clicker').subscribe(() => {
      console.log("Hey what do you know, I'm leaking");
    });
  }
}

this.store.select('clicker') возвращает наблюдаемое, что мы регистрируем новый обработчик для него при каждом вызове doSomethingUnthinkableManyTimes без очистки, что приводит к утечке памяти, которая будет сохраняться до тех пор, пока существует служба (время жизни приложения во многих случаях)

Суть в том, что вам не нужно отписываться в вышеупомянутом Http, как Владимир объяснил это хорошо, но в других случаях вам это может понадобиться.