#angular #rxjs
#angular #rxjs
Вопрос:
У меня есть фрагмент, который запрашивает у сервера статус оплаты пользователя. Это происходит каждые 5 секунд, пока статус не стал ожидаемым.
this.activatedRoute.params.subscribe((params: {orderId: string}) => {
let subscription = interval(5000)
.pipe(
startWith(0),
switchMap(() => this.paymentService.getStatusGuest(params.orderId)),
)
.subscribe((order: {status: string, amount?: number, message?: string}) => {
if(order.status == 'error') {
this.flashMessageService.set('error', order.message);
} else {
this.order = order;
}
if(order.status == 2 || order.status == 6 || order.status == -2)
subscription.unsubscribe();
});
});
Теперь я хочу показать предварительный загрузчик, когда выполняется опрос. Как я должен определить начало интервальной итерации?
Ответ №1:
Одним из способов сделать это может быть tap()
оператор, который можно использовать для выполнения побочного эффекта:
const subscription = this.activatedRoute.params
.pipe(
switchMap((params: {orderId: string}) => interval(5000)),
tap(() => showPreloader()) // <-- PRELOADER SHOWN HERE
startWith(0),
switchMap(() => this.paymentService.getStatusGuest(params.orderId)),
)
.subscribe((order: {status: string, amount?: number, message?: string}) => {
if(order.status == 'error') {
this.flashMessageService.set('error', order.message);
} else {
this.order = order;
}
if(order.status == 2 || order.status == 6 || order.status == -2)
subscription.unsubscribe();
});
Другим способом сделать это без побочных эффектов может быть наличие двух подписок на интервал, так что что-то вроде этого:
const intervalBeginning$ = this.activatedRoute.params.pipe(
switchMap((params: {orderId: string}) => interval(5000))
);
const paymentStatusSubscripton = intervalBeginning$.pipe(
startWith(0),
switchMap(() => this.paymentService.getStatusGuest(params.orderId)),
)
.subscribe((order: {status: string, amount?: number, message?: string}) => {
if(order.status == 'error') {
this.flashMessageService.set('error', order.message);
} else {
this.order = order;
}
if(order.status == 2 || order.status == 6 || order.status == -2) {
paymentStatusSubscripton.unsubscribe();
showPreloaderSubscripton.unsubscribe();
}
});
const showPreloaderSubscripton = intervalBeginning$.subscribe(() => {
showPreloader(); // <-- PRELOADER SHOWN HERE
});