Сброс тайм-аута при каждом вызове функции Angular2 RxJS
У меня есть запрос http, который запускается, если пользователь вводит по крайней мере 4 символа во входе и срабатывает каждый раз, когда он меняет свой контент (добавление / удаление букв). Я хочу добавить тайм-аут, что если пользователь начинает вводить символы, функция будет ждать 1 секунду, пока не сработает запрос, чтобы избежать большого количества запросов, когда пользователь печатает быстро. Моя попытка:
if (this.pointName.length >= 3) {
let timer = function() {
this.http.get(`./points.json`)
.subscribe(res => {
this.pointsArray = res.json();
});
};
clearTimeout(timer);
setTimeout(timer,1000);
Моя идея состояла в том, чтобы очистить тайм-аут на каждом keyup
событие и установить его еще раз. Но, к сожалению, это дает мне ошибку, что `Аргумент типа '() => void' не может быть назначен параметру типа 'номер'.
Есть ли способ сделать это более эффективно? Может быть, используя RxJS? В любом случае, я ищу рабочее решение. Заранее спасибо.
HTML
<input type="text" id="searchInput" placeholder="Point name"(keyup)="getPoints()">
3 ответа
Почему бы не использовать debounceTime(500) вместо setTimeout.
https://www.learnrxjs.io/operators/filtering/debouncetime.html
Прежде всего, вам лучше использовать Debounce
оператор в RxJS. И проблема в вашем коде в том, что вы должны передать timer_id
в clearTimeout
вместо функции.
if (this.pointName.length >= 3) {
let timer = function() {
this.http.get(`./points.json`)
.subscribe(res => {
this.pointsArray = res.json();
});
};
let timer_id = undefined;
clearTimeout(timer_id);
timer_id = setTimeout(timer,1000);
Попробуй это:
Создайте тему RxJS как новую переменную-член вашего компонента
searchTerm$ = new Subject<string>();
В методе ngOnInit вашего компонента, установите ваш наблюдаемый,
ngOnInit() {
this.searchTerm$
.filter( value => value.length >= 3)
.debounceTime(1000)
.switchMap( val => {
return this.http.get('./points.json')
.map(result => result.json());
})
.subscribe(result => .... // do what you want with the response );
}
В своем HTML измените привязку события keyup, чтобы передать значение поля ввода
<input type="text" id="searchInput" placeholder="Point name"(keyup)="getPoints(this.value)">
Затем в методе getPoints вашего компонента отправьте значение в ваш объект $
getPoints(value) {
this.subject$.next(value);
}
По сути, наблюдаемая вами вещь делает несколько вещей:
searchTerm$
.filter( value => value.length >= 3) // 1 filter out search terms that are shorter than 3 characters
.debounceTime(1000) // 2. only send events after no event comes for 1 sec
.switchMap( val => { // 3. convert your value to the result of your http request
return this.http.get('./points.json')
.map(result => result.json());
})
.subscribe(result => .... // do what you want with the response );