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('todos'); } }
구성요소가 destroy, async 파이프라인은 메모리 누수의 위험을 피하기 위해 구독 취소 작업을 자동으로 수행합니다.
Angular AsyncPipe 소스 코드 조각
@Pipe({name: 'async', pure: false}) export class AsyncPipe implements OnDestroy, PipeTransform { // ... constructor(private _ref: ChangeDetectorRef) {} ngOnDestroy(): void { if (this._subscription) { this._dispose(); } } }
@HostListener
export class TestDirective { @HostListener('click') onClick() { .... } }
@HostListener 데코레이터를 사용하는 경우 이벤트 리스너를 추가할 때 구독을 취소할 수 없습니다 수동으로. 이벤트 수신을 수동으로 제거해야 하는 경우 다음 방법을 사용할 수 있습니다.
// subscribe this.handler = this.renderer.listen('document', "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('http://api.com').subscribe(console.log); } }
공개 정적 타이머 (ENITIAL : NUTERDELAY : 번호 날짜, 기간 : 번호, 스케줄러 : Scheduler): 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));
export class TestComponent { constructor(private store: Store) { } private componetDestroyed: Subject = new Subject(); todos: Subscription; posts: Subscription; ngOnInit() { this.todos = this.store.select('todos') .takeUntil(this.componetDestroyed).subscribe(console.log); this.posts = this.store.select('posts') .takeUntil(this.componetDestroyed).subscribe(console.log); } ngOnDestroy() { this.componetDestroyed.next(); this.componetDestroyed.unsubscribe(); } }
takeUntil 연산자
Operator 서명
public takeUntil(notifier: Observable): Observable<T>
var interval = Rx.Observable.interval(1000); var clicks = Rx.Observable.fromEvent(document, 'click'); var result = interval.takeUntil(clicks); result.subscribe(x => console.log(x));
AngularJS의 양식 유효성 검사에 대한 자세한 설명
AngularJS에 대한 자세한 설명 필터 정의_AngularJS
위 내용은 Angular에서 구독을 취소하는 경우에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!