[javascript] Angular2에서 구독을 취소하는 방법

Angular2에서 구독을 어떻게 취소합니까? RxJS에 처리 방법이있는 것 같지만 액세스 방법을 알 수 없습니다. 그래서 다음과 같이 EventEmitter에 대한 액세스 권한이 있고 구독하는 코드가 있습니다.

var mySubscription = someEventEmitter.subscribe(
    (val) => {
        console.log('Received:', val);
    },
    (err) => {
        console.log('Received error:', err);
    },
    () => {
        console.log('Completed');
    }
);

어떻게 사용할 수있는 mySubscription구독을 취소하려면?



답변

구독을 취소 하시겠습니까?

mySubscription.unsubscribe();


답변

나도 2 센트를 넣었다고 생각했다. 이 패턴을 사용합니다.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

@Component({
    selector: 'my-component',
    templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {

    private subscriptions: Array<Subscription> = [];

    public ngOnInit(): void {
        this.subscriptions.push(this.someService.change.subscribe(() => {
            [...]
        }));

        this.subscriptions.push(this.someOtherService.select.subscribe(() => {
            [...]
        }));
    }

    public ngOnDestroy(): void {
        this.subscriptions.forEach((subscription: Subscription) => {
            subscription.unsubscribe();
        });
    }
}

편집하다

요 전에 문서를 읽고 더 권장되는 패턴을 찾았습니다.

ReactiveX / RxJS / 구독

장점 :

내부적으로 새 구독을 관리하고 몇 가지 깔끔한 검사를 추가합니다. 기능 에서이 방법을 선호합니다 :).

단점 :

코드 흐름이 무엇인지, 구독이 어떻게 영향을 받는지는 100 % 명확하지 않습니다. 종료 된 구독을 처리하는 방법과 구독 취소가 호출되면 모든 구독이 종료되는지 여부도 코드를 보면 명확하지 않습니다.

import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';

@Component({
    selector: 'my-component',
    templateUrl: 'my.component.html'
})
export class MyComponent implements OnInit, OnDestroy {

    private subscription: Subscription = new Subscription();

    public ngOnInit(): void {
        this.subscription.add(this.someService.change.subscribe(() => {
            [...]
        }));

        this.subscription.add(this.someOtherService.select.subscribe(() => {
            [...]
        }));
    }

    public ngOnDestroy(): void {
        /*
         * magic kicks in here: All subscriptions which were added
         * with "subscription.add" are canceled too!
         */
        this.subscription.unsubscribe();
    }
}


답변

편집 : 이것은 angular2가 사용하는 RxJS 5에는 적용되지 않습니다.

Disposable 에서 dispose 메서드를 찾고 있다고 생각했을 것 입니다.

subscribe 메서드는 Disposable ( link )을 반환합니다.

문서에서 더 명시 적으로 찾을 수없는 것 같지만 작동합니다 ( jsbin ).

var observable = Rx.Observable.interval(100);

var subscription = observable.subscribe(function(value) {
   console.log(value);
});

setTimeout(function() {
  subscription.dispose();
}, 1000)

이상하게도 구독 취소가 효과가있는 것 같습니다.


답변

ng2에 대한 Observables 구독 취소에 대한 너무 많은 설명 때문에 올바른 답을 찾는 데 오랜 시간이 걸렸습니다. 아래는 실제 예제입니다 (mousemove를 조절하려고했습니다).

import {Injectable, OnDestroy} from "@angular/core";
import {Subscription} from "rxjs";

@Injectable()
export class MyClass implements OnDestroy {

  mouseSubscription: Subscription; //Set a variable for your subscription

  myFunct() {
    // I'm trying to throttle mousemove
    const eachSecond$ = Observable.timer(0, 1000);
    const mouseMove$ = Observable.fromEvent<MouseEvent>(document, 'mousemove');
    const mouseMoveEachSecond$ = mouseMove$.sample(eachSecond$);

    this.mouseSubscription = mouseMoveEachSecond$.subscribe(() => this.doSomethingElse());
  }

  doSomethingElse() {
    console.log("mouse moved");
  }

  stopNow() {
    this.mouseSubscription.unsubscribe();
  }

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

}


답변

ngOnDestroy(){
   mySubscription.unsubscribe();
}

구성 요소를 파괴하는 동안 rxjs 구독 취소를 선호합니다. 즉, 불필요한 메모리 누수를 방지하기 위해 DOM에서 제거합니다.


답변

나는 개인적으로 Subject를 사용하여 구성 요소가 파괴 수명주기 단계에서 가질 수있는 모든 구독을 닫는 것을 선호합니다.

import { Component} from '@angular/core';
import { Subject } from "rxjs/Rx";

@Component({
  selector:    'some-class-app',
  templateUrl: './someClass.component.html',
  providers:   []
})

export class SomeClass {

  private ngUnsubscribe: Subject<void> = new Subject<void>(); //This subject will tell every subscriptions to stop when the component is destroyed.

  //**********
  constructor() {}

  ngOnInit() {

    this.http.post( "SomeUrl.com", {}, null ).map( response => {

      console.log( "Yay." );

    }).takeUntil( this.ngUnsubscribe ).subscribe(); //This is where you tell the subscription to stop whenever the component will be destroyed.
  }

  ngOnDestroy() {

    //This is where we close any active subscription.
    this.ngUnsubscribe.next();
    this.ngUnsubscribe.complete();
  }
}


답변

권장되는 접근 방식은 takeUntil 연산자와 같은 RxJS 연산자를 사용하는 입니다. 다음은 사용 방법을 보여주는 코드 스 니펫입니다.

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

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html'
})
export class AppComponent implements OnInit, OnDestroy {
    private ngUnsubscribe = new Subject();

    constructor() { }

    ngOnInit() {
        var observable1 = interval(1000);
        var observable2 = interval(2000);

        observable1.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable1: ' + x));
        observable2.pipe(takeUntil(this.ngUnsubscribe)).subscribe(x => console.log('observable2: ' + x));
    }

    ngOnDestroy() {
        this.ngUnsubscribe.next();
        this.ngUnsubscribe.complete();
    }
}

여기 에서 주제에 대한 자세한 설명을 찾을 수 있습니다.