Наблюдаемый 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() просто для того, чтобы убедиться, что пользовательский интерфейс обновляется, несмотря на любые обстоятельства. Надеюсь это поможет..

Другие вопросы по тегам