При клике на кнопку срабатывает метод getDatafromServer. Подскажите, правильно ли в Angular реализован switchMap для одного роута т.е. при повторном нажатии отменяется предыдущий запрос (если еще не пришел старый) и отправляется новый:
getDatafromServer() {
of(`url1`).pipe(switchMap(url => this.httpGeneralService.getDataFromJsonServer(url))).
subscribe(i => console.log(i));
}
Вроде все верно, но в браузере в Network не видно, чтобы отменялись предыдущие запросы
UPD: похоже этот вариант рабочий:
private requestPasswordSubject$ = new Subject();
private requestPassword = this.requestPasswordSubject$.pipe(
switchMap(() => this.httpGeneralService.getDataFromJsonServer(`url1`))
)
.subscribe(response => { console.log(response); } );
getDatafromServer() {
this.requestPasswordSubject$.next();
}
switchMap будет работать правильно в том случае, если события по нажатию на кнопку будут идти из потока. В данном случае:
of(`url1`).pipe(switchMap(url => this.httpGeneralService.getDataFromJsonServer(url)))
of('url1') - это холодный поток, который сгенерирует событие 1 раз и закроется (вопрос зачем вы так делаете?) Я бы сказал это бесполезный код.
Если вы хотите по клику на кнопку отправлять запрос и отписываться от потока, если не пришел ответ, но пришло новое событие - нужно использовать связку fromEvent + switchMap:
const button = document.querySelector('button');
fromEvent(button, 'click').pipe(
switchMap(() => this.httpGeneralService.getDataFromJsonServer(`url1`))
).subscribe((response) => {
console.log(response);
});
switchMap подписывается на поток fromEvent, параметром принимает фабрику (в концепции RxJS это называется проекция), вызывает эту фабрику и результатом получает новый поток (который возвращает this.httpGeneralService.getDataFromJsonServer('url1')), подписывается на этот поток, ждет ответа, если fromEvent сгенерирует событие раньше чем поток getDataFromJsonServer - SwitchMapSubscriber отписывается от getDataFromJsonServer и обрабатывает новое поступившее событие из потока fromEvent.
_next(value) {
let result;
const index = this.index++;
try {
result = this.project(value, index); // вызвали проекцию и получили поток
}
catch (error) {
this.destination.error(error);
return;
}
this._innerSub(result, value, index);
}
_innerSub(result, value, index) {
const innerSubscription = this.innerSubscription;
if (innerSubscription) {
innerSubscription.unsubscribe(); // отписываемся от предыдущей проекции
}
}
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости