Как отписаться внутри подписки rxjs, когда будет выполнено условие
ts:
import {interval, of, Subscription, Observable, takeUntil} from 'rxjs';
private statusSubscription: Subscription;
ngOnInit() {
this.infoSubscription = interval(1000)
.pipe(switchMap(() => this.service.getInfo()),takeUntil(res => res.body.message === 'End')
.subscribe((res) => {
console.log(res.body.message)
if (res.body.message === 'End'){
console.log('Конец')}
})
}
Данный способ вообще ничего не выполняет. Либо использовать takeWhile(res => res.body.message !== 'End')
Но он отписывается, и не выводит в консоль последнее значение перед отпиской.
Ответы (1 шт):
Автор решения: Nikolya Shirshov
→ Ссылка
- В первом случае ничего не происходит т.к.
takeUntilдолжен приниматьObservable, а неcallback. - Во втором случае вы не получаете значение в
next callback, т.к.Observableзавершается (complete), не доходя доnext. Если у вас версия RxJs выше v6.4, можете передать в операторtakeWhileвторым аргументомtrue, тогда последнее значение будет передано вnext.
Вы можете отписаться внутри subscribe next callback при необходимом условии.
Пример 1:
ngOnInit() {
this.infoSubscription = interval(1000)
.pipe(switchMap(() => this.service.getInfo()))
.subscribe((res) => {
if (res.body.message === 'End'){
this.infoSubscription.unsubscribe();
}
})
}
Пример 2 (takeUntil):
unsubscribe$: Subject<void> = new Subject();
ngOnInit() {
interval(1000)
.pipe(
switchMap(() => this.service.getInfo()),
takeUntil(this.unsubscribe$)
)
.subscribe((res) => {
if (res.body.message === 'End'){
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
})
}
Пример 3 (takeWhile):
ngOnInit() {
interval(1000)
.pipe(
switchMap(() => this.service.getInfo()),
takeWhile((res) => res.body.message !== 'End', true)
)
.subscribe((res) => {
if (res.body.message === 'End'){
console.log('End')
}
})
}