Я хочу создать функцию, которая будет выполнять запросы AJAX к бэкэнду. И если эта функция вызывается много раз одновременно, то она не должна делать много одинаковых запросов к серверу. Он должен сделать только 1 запрос.
Например:
doAJAX('http://example-1.com/').subscribe(res => console.log); // must send a request
doAJAX('http://example-1.com/').subscribe(res => console.log); // must NOT send a request
doAJAX('http://example-2.com/').subscribe(res => console.log); // must send a request, bacause of different URL
window.setTimeout(() => {
doAJAX('http://example-2.com/').subscribe(res => console.log); // must send a request because too much time has passed since the last request
}, 3000)
Все вызовы функций должны возвращать результат, как если бы запрос был фактически выполнен.
Я думаю, что для этой цели я могу использовать библиотеку RxJS.
Я сделал это:
const request$ = new Subject < string > ();
const response$ = request.pipe(
groupBy((url: string) => url),
flatMap(group => group.pipe(auditTime(500))), // make a request no more than once every 500 msec
map((url: string) => [
url,
from(fetch(url))
]),
share()
);
const doAJAX = (url: string): Observable <any> {
return new Observable(observe => {
response$
.pipe(
filter(result => result[0] === url),
first(),
flatMap(result => result[1])
)
.subscribe(
(response: any) => {
observe.next(response);
observe.complete();
},
err => {
observe.error(err);
}
);
request$.next(url);
});
}
Я создаю request$
тему и response$
наблюдаемую. Функция doAjax
подписывается на response$
и отправляет строку URL в тему request$
. Также в потоке request$
есть операторы groupBy
и auditTime
. И оператор фильтра в функции doAJAX
.
Этот код работает, но я думаю, что это очень сложно. Есть ли способ облегчить эту задачу? Может быть, планировщик RxJS или не использовать библиотеку RxJS вообще