Наблюдаемый ForkJoin не отписывается, когда ngOnDestroy
Так что у моего приложения есть всплывающее окно, оно имеет наблюдаемое forkjoin, которое может занять много времени, если пользователь выберет много элементов. Если пользователь закрывает окно во время процесса, приложение будет стоять на месте, пока не завершится выполнение forkjoin, и в моем основном приложении ничего не будет работать. Я отменяю подписку на forkjoin, используя подписку, но она все еще работает, пока не будет завершена. Вот мой код:
subscriptions: Subscription[] = [];
ngOnDestroy() {
// prevent memory leak when component destroyed
this.subscriptions.forEach(s => s.unsubscribe());
}
//get all my items
getItems() {
//set item list to blank
this.itemList = [];
let observables = [];
this.loadItems = true;
//get sections that user selected
this.subscriptions.push(
this.organizationService.GetSelectedSections(this.sectionID, this.culture)
.subscribe(
(selectedSections: GetSelectedSections[]) => {
this.selectedSectionsAll = selectedSections;
//push all selected sections in observables
for (let section in selectedSections) {
observables.push(this.organizationService.GetItemsBySection( selectedSections[section].sectionItemID, this.culture));
}
// get all items in sections to display
if (observables.length != 0) {
this.subscriptions.push(
Observable.forkJoin(observables)
.subscribe(
(result: any) => {
this.itemList = result;
},
(error: any) => {
this.errorMessage = error
this.loadItems = false;
},
() => {
this.loadItems = false;
}
)
);
}
},
(error: any) => {
this.errorMessage = error
},
() => {
}
)
);
}
1 ответ
Со временем я понял, что правильная очистка ваших наблюдений - это просто хорошая практика. Как правило, в моем ngDestroy у меня есть:
ngOnDestroy() {
this.updateService.clearUpdate(); //this is where I call the next() method
//on the observable to clear it
this.subscription.unsubscribe(); //I call this directly on the Subscription object
//To clear obviously unsubscribe
this.alive = false; //I use this in the subscribed method in my component
//as a boolean for the rxjs takeWhile() method...
}
один из моих типичных пабов / сабов
this.updateService.getUpdate()
.takeWhile(() => this.alive)
.subscribe(message => {...impl...}
моя структура обмена сообщениями всегда является внешней от класса компонента и очень проста
public message = new Subject<any>();
constructor(private zone: NgZone) {
}
sendUpdate(message) {
this.zone.run(() => {
this.message.next(message);
});
}
getUpdate(): Observable<any> {
this.zone.run(() => {
this.message.asObservable();
});
return this.message.asObservable();
}
clearUpdate() {
this.zone.run(() => {
this.message.next();
});
}
Я держу вещи простыми, насколько это возможно. Я также использую angular's zone() просто для того, чтобы убедиться, что пользовательский интерфейс обновляется, несмотря на любые обстоятельства. Надеюсь это поможет..