--- 편집 4-추가 리소스 (2018/09/01)
Angular Ben Lesh와 Ward Bell 의 최근 모험 에피소드 에서 구성 요소를 구독 취소하는 방법 / 언제와 관련된 문제에 대해 설명합니다. 토론은 약 1:05:30에 시작됩니다.
와드 언급 right now there's an awful takeUntil dance that takes a lot of machinery
과 샤이 레즈 닉 언급 Angular handles some of the subscriptions like http and routing
.
이에 대한 응답으로 Ben은 Observables가 Angular 구성 요소 수명주기 이벤트에 연결될 수 있도록하기위한 논의가 있다고 언급했으며 Ward는 구성 요소 내부 상태로 유지되는 Observable을 완료 할시기를 알기위한 방법으로 구성 요소가 가입 할 수있는 Observable 수명주기 이벤트를 제안합니다.
즉, 현재 대부분 솔루션이 필요하므로 여기에 다른 리소스가 있습니다.
takeUntil()
RxJs 핵심 팀 멤버 Nicholas Jamieson 의 패턴에 대한 권장 사항 과이를 강화하는 데 도움이되는 tslint 규칙. https://ncjamieson.com/avoiding-takeuntil-leaks/
구성 요소 인스턴스 ( this
)를 매개 변수로 사용하고 자동으로 구독을 취소 하는 Observable 연산자를 제공하는 경량 npm 패키지 ngOnDestroy
.
https://github.com/NetanelBasal/ngx-take-until-destroy
AOT 빌드를하지 않으면 위의 또 다른 변형이 약간 더 인체 공학적입니다 (그러나 우리는 모두 AOT를해야합니다).
https://github.com/smnbbrv/ngx-rx-collector
*ngSubscribe
비동기 파이프처럼 작동하지만 템플릿에 포함 된 뷰를 생성하여 템플릿 전체에서 '포장 해제'값을 참조 할 수있는 사용자 지정 지시문 .
https://netbasal.com/diy-subscription-handling-directive-in-angular-c8f6e762697f
필자는 Nicholas의 블로그에 대한 과다 사용은 takeUntil()
구성 요소가 너무 많은 노력을 기울이고 있고 기존 구성 요소를 Feature 및 Presentational 구성 요소로 분리해야한다는 신호일 수 있다고 언급했습니다 . 그런 다음 | async
Feature 구성 요소 Input
에서 Presentational 구성 요소로 Observable을 사용할 수 있습니다. 즉, 구독이 필요하지 않습니다. 이 방법에 대한 자세한 내용은 여기를 참조하십시오
--- 편집 3- '공식적인'솔루션 (2017/04/09)
나는 NGConf 에서이 질문에 대해 Ward Bell과 이야기했다. (나는 그에게 그가 옳았다 고 대답했다. ). 그는 또한 다음 공식 추천으로 내 SO 답변을 업데이트 할 수 있다고 말했습니다.
앞으로 우리 모두가 사용해야 할 해결책은 클래스 코드 내에서 호출하는 private ngUnsubscribe = new Subject();
모든 구성 요소에 필드를 추가하는 것 입니다 ..subscribe()
Observable
우리는 전화를 this.ngUnsubscribe.next(); this.ngUnsubscribe.complete();
우리의 ngOnDestroy()
방법.
비밀 소스 ( @metamaker에서 이미 언급 한 바와 같이 )는 takeUntil(this.ngUnsubscribe)
각 호출 전에 .subscribe()
호출하여 구성 요소가 파괴 될 때 모든 구독이 정리되도록합니다.
예:
import { Component, OnDestroy, OnInit } from '@angular/core';
// RxJs 6.x+ import paths
import { filter, startWith, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { BookService } from '../books.service';
@Component({
selector: 'app-books',
templateUrl: './books.component.html'
})
export class BooksComponent implements OnDestroy, OnInit {
private ngUnsubscribe = new Subject();
constructor(private booksService: BookService) { }
ngOnInit() {
this.booksService.getBooks()
.pipe(
startWith([]),
filter(books => books.length > 0),
takeUntil(this.ngUnsubscribe)
)
.subscribe(books => console.log(books));
this.booksService.getArchivedBooks()
.pipe(takeUntil(this.ngUnsubscribe))
.subscribe(archivedBooks => console.log(archivedBooks));
}
ngOnDestroy() {
this.ngUnsubscribe.next();
this.ngUnsubscribe.complete();
}
}
참고 :takeUntil
작업자 체인의 중간 관측 가능 장치에서 누출을 방지 하려면 연산자를 마지막 연산자로 추가해야합니다 .
--- 편집 2 (2016/12/28)
소스 5
Angular tutorial의 Routing 장은 이제 다음과 같이 말합니다 : "라우터는 제공하는 옵저버 블을 관리하고 서브 스크립 션을 현지화합니다. 서브 스크립 션은 컴포넌트가 파괴 될 때 정리되어 메모리 누수를 방지하므로 구독을 취소 할 필요가 없습니다. 경로 매개 변수를 관찰 할 수 있습니다. " - 마크 라지 콕
여기의 논의 워드 벨이의 모든 것을 해명이 작품에 언급 경우 라우터 Observable 인에 대한 각 문서에 대한 Github의 문제에가.
--- 편집 1
소스 4
이러한면에서 NgEurope의 비디오 롭 Wormald 또한 라우터 Observables은 가입을 취소 할 필요가 없습니다 말했다. 그는 또한 언급 http
서비스와 ActivatedRoute.params
이에 2016년 11월에서 비디오를 .
--- 원래 답변
TLDR :
이 질문에 대해 (2) 종류가있다 Observables
- 유한 값과 무한 값.
http
Observables
생산 한정된 (1)의 값과 같은 것을 DOM은 event listener
Observables
생산 무한 값.
subscribe
비동기 파이프를 사용하지 않고 수동으로 호출하면 infiniteunsubscribe
에서 호출 합니다. Observables
유한 한 것들 에 대해 걱정하지 마십시오 RxJs
.
소스 1
나는 각도의 Gitter에서 롭 Wormald에서 답변을 추적 여기 .
그는 말한다 (명확하고 강조하기 위해 재구성되었다)
그 경우 단일 값 시퀀스 (HTTP 요청 등)를 수동으로 정리 불필요 (수동 컨트롤러에 가입 가정)
" 완료된 시퀀스 인 경우 "(단일 값 시퀀스, la http 중 하나)
그 무한 순서 경우 , 당신은 취소해야 비동기 파이프가 당신을 위해 수행하는
또한 Observables에 대한 이 YouTube 비디오 에서 they clean up after themselves
... Observables 의 맥락에서 complete
(Promises와 같이 항상 1 개의 가치를 창출하고 끝나기 때문에 완료되는 약속과 같이) xhr
이벤트 를 정리하기 위해 Promises에서 구독을 취소하는 것에 대해 걱정하지 않습니다. 청취자, 그렇지?).
소스 2
또한 Angular 2 의 Rangle 안내서에서 읽습니다.
대부분의 경우 조기 취소를 원하거나 Observable이 구독보다 수명이 길지 않으면 구독 취소 메소드를 명시 적으로 호출 할 필요가 없습니다. Observable 연산자의 기본 동작은 .complete () 또는 .error () 메시지가 게시되는 즉시 구독을 처리하는 것입니다. RxJS는 대부분 "화재와 잊어 버리기"방식으로 사용되도록 설계되었습니다.
문구는 언제 our Observable has a longer lifespan than our subscription
적용됩니까?
구성 요소 내부에서 구독이 작성 될 때 적용되며 Observable
완료 되기 전에 (또는 오래 전에는) 소멸 됩니다.
http
10 개의 값을 방출 하는 요청 또는 옵저버 블에 가입 하고 http
요청이 반환 되기 전에 구성 요소가 파괴 되거나 10 개의 값이 방출 된 경우에도 이것을 의미로 읽습니다 .
요청이 리턴되거나 10 번째 값이 최종적으로 방출 Observable
되면 완료되고 모든 자원이 정리됩니다.
소스 3
우리 가 동일한 Rangle 안내서 에서이 예제 를 보면 Subscription
to route.params
가 필요할 unsubscribe()
때 알 수 없기 때문에 to 가 필요 하다는 것을 알 수 있습니다 params
(새 값 방출).
경로 매개 변수가 계속 변경 될 가능성이있는 경우 (앱이 종료 될 때까지 기술적으로 변경 될 수 있음) 탐색하지 않으면 구성 요소가 손상 될 수 있으며 구독에 할당 된 리소스는 아직 없기 때문에 할당 completion
됩니다.
Subscription
s를http-requests
무시할 수 있다고 생각onNext
합니다onComplete
. 는Router
대신 호출onNext
반복적으로 호출하지 않을 수도 있습니다onComplete
(하지 않도록 ... 그것에 대해).Observable
에서Event
s도 마찬가지입니다 . 그래서 그럴 것 같아요unsubscribed
.