>웹 프론트엔드 >JS 튜토리얼 >Angular에서 구독을 취소하는 경우에 대한 자세한 설명

Angular에서 구독을 취소하는 경우에 대한 자세한 설명

小云云
小云云원래의
2017-12-12 11:05:291636검색

Observable 객체를 구독하거나 이벤트 리스너를 설정할 때 어느 시점에서는 운영 체제의 메모리를 해제하기 위해 구독 취소 작업을 수행해야 한다는 것을 알고 계실 것입니다. 그렇지 않으면 애플리케이션에 메모리 누수가 발생할 수 있습니다.

ngOnDestroy 수명 주기 후크에서 구독 취소 작업을 수동으로 수행해야 하는 몇 가지 일반적인 시나리오를 살펴보겠습니다. 이번 글은 Angular에서 언제 구독을 취소해야 하는지에 대한 간략한 논의를 주로 소개하고 있는데, 편집자는 꽤 좋다고 생각해서 공유하고 참고하겠습니다. 편집자를 따라 살펴보겠습니다. 모두에게 도움이 되기를 바랍니다.

수동 릴리스 리소스 시나리오

Form


export class TestComponent {

 ngOnInit() {
  this.form = new FormGroup({...});
  // 监听表单值的变化
  this.valueChanges = this.form.valueChanges.subscribe(console.log);
  // 监听表单状态的变化              
  this.statusChanges = this.form.statusChanges.subscribe(console.log);
 }

 ngOnDestroy() {
  this.valueChanges.unsubscribe();
  this.statusChanges.unsubscribe();
 }
}


위 솔루션은 다른 양식 컨트롤에도 적용 가능합니다.

Routing


export class TestComponent {
 constructor(private route: ActivatedRoute, private router: Router) { }

 ngOnInit() {
  this.route.params.subscribe(console.log);
  this.route.queryParams.subscribe(console.log);
  this.route.fragment.subscribe(console.log);
  this.route.data.subscribe(console.log);
  this.route.url.subscribe(console.log);
  
  this.router.events.subscribe(console.log);
 }

 ngOnDestroy() {
  // 手动执行取消订阅的操作
 }
}


Renderer service


export class TestComponent {
 constructor(
  private renderer: Renderer2, 
  private element : ElementRef) { }

 ngOnInit() {
  this.click = this.renderer
    .listen(this.element.nativeElement, "click", handler);
 }

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


Infinite Observables

을 사용하는 경우 fromEven t() 연산자를 사용하면 무한한 Observable 객체를 생성할 수 있습니다. 이 경우 더 이상 사용할 필요가 없으면 수동으로 리소스 구독을 취소하고 해제해야 합니다.


export class TestComponent {
 constructor(private element : ElementRef) { }

 interval: Subscription;
 click: Subscription;

 ngOnInit() {
  this.interval = Observable.interval(1000).subscribe(console.log);
  this.click = Observable.fromEvent(this.element.nativeElement, 'click')
              .subscribe(console.log);
 }

 ngOnDestroy() {
  this.interval.unsubscribe();
  this.click.unsubscribe();
 }
}


Redux Store


export class TestComponent {

 constructor(private store: Store) { }

 todos: Subscription;

 ngOnInit() {
   /**
   * select(key : string) {
   *  return this.map(state => state[key]).distinctUntilChanged();
   * }
   */
   this.todos = this.store.select('todos').subscribe(console.log); 
 }

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


수동으로 리소스 시나리오를 해제할 필요 없음

AsyncPipe


@Component({
 selector: 'test',
 template: `<todos [todos]="todos$ | async"></todos>`
})
export class TestComponent {
 constructor(private store: Store) { }
 
 ngOnInit() {
   this.todos$ = this.store.select(&#39;todos&#39;);
 }
}


구성요소가 destroy, async 파이프라인은 메모리 누수의 위험을 피하기 위해 구독 취소 작업을 자동으로 수행합니다.

Angular AsyncPipe 소스 코드 조각


@Pipe({name: &#39;async&#39;, pure: false})
export class AsyncPipe implements OnDestroy, PipeTransform {
 // ...
 constructor(private _ref: ChangeDetectorRef) {}

 ngOnDestroy(): void {
  if (this._subscription) {
   this._dispose();
  }
 }
}


@HostListener


export class TestDirective {
 @HostListener(&#39;click&#39;)
 onClick() {
  ....
 }
}


@HostListener 데코레이터를 사용하는 경우 이벤트 리스너를 추가할 때 구독을 취소할 수 없습니다 수동으로. 이벤트 수신을 수동으로 제거해야 하는 경우 다음 방법을 사용할 수 있습니다.


// subscribe
this.handler = this.renderer.listen(&#39;document&#39;, "click", event =>{...});

// unsubscribe
this.handler();


Finite Observable

HTTP 서비스 또는 타이머 Observable 객체를 사용할 때 수동으로 구독을 취소할 필요가 없습니다. . Code 코드는 다음과 같습니다.


r

export class TestComponent {
 constructor(private http: Http) { }

 ngOnInit() {
  // 表示1s后发出值,然后就结束了
  Observable.timer(1000).subscribe(console.log);
  this.http.get(&#39;http://api.com&#39;).subscribe(console.log);
 }
}
eeTimer 연산자 연산자 Signature restature Code 례 :


공개 정적 타이머 (ENITIAL : NUTERDELAY : 번호 날짜, 기간 : 번호, 스케줄러 : Scheduler): Observable


Operator function


timer는 특정 시간 간격으로 무한 자동 증가 시퀀스를 내보내는 Observable을 반환합니다.

Operator 예제



// 每隔1秒发出自增的数字,3秒后开始发送
var numbers = Rx.Observable.timer(3000, 1000);
numbers.subscribe(x => console.log(x));

// 5秒后发出一个数字
var numbers = Rx.Observable.timer(5000);
numbers.subscribe(x => console.log(x));


최종 제안


Subscribe() 메소드를 가능한 한 적게 호출해야 합니다. RxJS: Don't Unsubscribe 자세한 정보에서 Subject에 대해 자세히 알아볼 수 있습니다.

구체적인 예는 다음과 같습니다.


export class TestComponent {
 constructor(private store: Store) { }

 private componetDestroyed: Subject = new Subject();
 todos: Subscription;
 posts: Subscription;

 ngOnInit() {
   this.todos = this.store.select(&#39;todos&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
           
   this.posts = this.store.select(&#39;posts&#39;)
           .takeUntil(this.componetDestroyed).subscribe(console.log); 
 }

 ngOnDestroy() {
  this.componetDestroyed.next();
  this.componetDestroyed.unsubscribe();
 }
}


takeUntil 연산자

Operator 서명

public takeUntil(notifier: Observable): Observable<T>


Operator 함수


Emit source Observable Observable 알림자가 값을 방출할 때까지 방출된 값 .

연산자 예제



var interval = Rx.Observable.interval(1000);
var clicks = Rx.Observable.fromEvent(document, &#39;click&#39;);
var result = interval.takeUntil(clicks);

result.subscribe(x => console.log(x));


관련 권장 사항:


AngularJS의 양식 유효성 검사에 대한 자세한 설명


AngularJS_AngularJ의 사용자 지정 지시문 사용에 대한 자세한 설명 S


AngularJS에 대한 자세한 설명 필터 정의_AngularJS

위 내용은 Angular에서 구독을 취소하는 경우에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.