Как начать обработку после того, как пользователь заканчивает печатать с помощью Rx JS? - PullRequest
0 голосов
/ 13 марта 2020

У меня есть элемент ввода, где я хочу показать решение для автозаполнения. Я пытаюсь контролировать номер HTTP-запроса с помощью Rx JS. Я хочу сделать: HTTP-запрос запускается только через 1 секунду, пользователь прекращает ввод.

У меня есть этот код:

of(this.inputBox.nativeElement.value)
  .pipe(
    take(1),
    map((e: any) => this.inputBox.nativeElement.value),
    // wait 1 second to start
    debounceTime(1000),
    // if value is the same, ignore
    distinctUntilChanged(),
    // start connection
    switchMap(term => this.autocompleteService.search({
      term: this.inputBox.nativeElement.value
    })),
  ).subscribe((result: AutocompleteResult[]) => {
    console.log(result);
  });

Проблема в том, что debounceTime(1000) не сделал ждать, чтобы продолжить трубу. SwitchMap запускается сразу после каждого события keyup.

Как можно подождать 1 секунду после того, как пользователь закончит ввод?

Ответы [ 2 ]

1 голос
/ 13 марта 2020

Проблема в том, что ваша цепочка начинается с of(this.inputBox.nativeElement.value).pipe(take(1), ...), поэтому создается впечатление, что вы создаете новую цепочку (с новым таймером восстановления) при каждом нажатии клавиши.

Вместо этого у вас должен быть только один Цепочка и pu sh значения к ее источнику:

const keyPress$ = new Subject();

...

keyPress$
  .pipe(
    debounceTime(1000),
    ...
  )

...

keyPress$.next(this.inputBox.nativeElement.value);
0 голосов
/ 13 марта 2020

Почему бы вам не создать поток с fromEvent?

Я не нашел необходимым использовать distinctUntiChanged, так как событие input срабатывает только при изменении (т. Е. Пользователь добавляет / удаляет вещи). Таким образом, текст, проходящий через поток, всегда отличается.

const {fromEvent} = rxjs;
const {debounceTime, map} = rxjs.operators;

const text$ =
  fromEvent(document.querySelector('input'), 'input')
    .pipe(
      debounceTime(1000),
      map(ev => ev.target.value));

text$.subscribe(txt => {
  console.log(txt);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/6.5.4/rxjs.umd.min.js"></script>
<input/>
...