У меня есть функция, которая выполняет http-запрос на основе параметра.И я хочу добавить какую-то функциональность "debounce".Поэтому, если функция вызывается несколько раз в заданном временном окне, я хочу объединить параметры в один запрос, а не делать несколько запросов.
Я хочу добиться этого с помощью Observables и Angular.Это не кажется сложным, однако я не могу запустить его, может быть, я что-то упустил.
А пока давайте просто пропустим объединение в одном запросе, поскольку это можно сделать с агрегированнымdebounce или Oberservable.buffer.У меня проблемы с объединением отдельных Observables.
Вот то, что я пробовал до сих пор.
Я пытался использовать Subject, так как это казалось подходящим объектом для этого случая (https://stackblitz.com/edit/angular-hcn41v?file=src%2Fapp%2Fapp.component.ts).
constructor(private http: HttpClient) {
this.makeRequest('1').subscribe(x => console.log(x))
this.makeRequest('2').subscribe(console.log)
setTimeout(() => {
this.makeRequest('3').subscribe(console.log)
}, 1000)
}
private makeRequest(id: string) {
this.observable = this.observable.pipe(
merge(Observable.of(id).pipe(delay(1)))
)
return this.aggregateDebounce(this.observable)
}
private getUrl(value) {
console.log('getUrl Call', value);
return 'https://jsonplaceholder.typicode.com/posts/1';
}
private aggregateDebounce(ob$) {
const shared$ = ob$.publishReplay(1).refCount()
return shared$.buffer(shared$.debounceTime(75))
}
Я ожидаю иметь один журнал 'getUrl Call' для каждого вызова функции и один журнал результатов.Однако я получаю результаты, только если я добавлю более 1 вызовов к this.makeRequest () и результат будеттакже странно. Все предыдущие значения также всегда возвращаются. Мне кажется, я не до конца понимаю, как Subject работает в этом случае.
Другой подход (взят отсюда RXJS: Aggregated debounce )было создать какой-то совокупный дебад (https://stackblitz.com/edit/angular-mx232d?file=src/app/app.component.ts)
constructor(private http: HttpClient) {
this.makeRequest('1').subscribe(x => console.log(x))
this.makeRequest('2').subscribe(console.log)
setTimeout(() => {
this.makeRequest('3').subscribe(console.log)
}, 1000)
}
private makeRequest(id: string) {
this.observable = this.observable.pipe(
merge(Observable.of(id).pipe(delay(1)))
)
return this.aggregateDebounce(this.observable)
}
private getUrl(value) {
console.log('getUrl Call', value);
return 'https://jsonplaceholder.typicode.com/posts/1';
}
private aggregateDebounce(ob$) {
const shared$ = ob$.publishReplay(1).refCount()
return shared$.buffer(shared$.debounceTime(75))
}
В этом сценарии у меня проблема, я также получаю все предыдущие значения.
В теории (по крайней мере,для меня) оба варианта звучат правдоподобно, однако кажется, что я что-то упустил. Любой миг в правильном направлении высоко ценится.
Редактировать:
По запросуЯ добавил финалЦель al-world.
Представьте себе сервис, который запрашивает информацию у API.В течение 50-75мс вы звоните в службу с определенным идентификатором.Я хочу сгруппировать эти идентификаторы вместе в один запрос вместо выполнения 3. И если через 100 мс будет сделан другой вызов в службу, будет выполнен новый запрос