Observables: отменить предыдущий запрос http при новом вызове по подписке. - PullRequest
0 голосов
/ 22 ноября 2018

Я работаю над функцией поиска для моего проекта.Как только пользователь что-нибудь наберет в строке поиска;при любом изменении в тексте поиска я буду отправлять текст в бэкэнд для проверки и получать ответ (ошибка или отсутствие ошибки в тексте):

this.searchBar.on('change', () => {

    http.post('api_link', {searchText: 
       this.serachBar.searchText}).subscribe(resp => {
            this.resp = resp['Result'];
       });
    })

Теперь, когда пользователь непрерывно печатает в строке поиска,несколько проверочных ответов поступают через серверную часть.Однако при любом новом изменении действительна только последняя подписка, а любой предыдущий вызов api бесполезен.

Можно ли как-нибудь отменить предыдущую подписку при любом новом вызове api, используя подписку?

Примечание: может показаться возможным просто подождать всех ответов, но я также собираюсь отобразить ответы под строкой поиска (показывая загрузчик до этого момента).Поэтому вместо перехода между различными состояниями ответа я хочу, чтобы загрузчик продолжал загружаться до тех пор, пока не будет доступен последний ответ.

Ответы [ 2 ]

0 голосов
/ 22 ноября 2018

Я бы использовал тему, чтобы все реагировало.в вашем шаблоне html слушайте изменения событий и отправляйте новое значение субъекту.

 <searchBar (change)="search$.next($event.target.value)" />

затем в вашем компоненте:

  this.subscription = this.search$.pipe(
     debounceTime(800), 
     distinctUntilChanged(),
     switchMap(searchText=>http.post('api_link', {searchText})
    }).subscribe(response=>{
       this.response = response.
    });

switchMap отменит любой запрос HTML, который не 't завершено, если через субъект выдается новое значение.Вы можете поиграть с debouneTime, чтобы увидеть, что вам подходит.И наконец, убедитесь, что вы отменили подписку на свою тему в ngOnDestroy, это предотвратит любые ссылки на память и сохранит все в порядке и правильности:является отличным дополнением к решению.Я добавляю это, но хочу отдать должное его ответу ниже.Это преимущество, потому что, если я ищу egg, запрос выполняется.но затем я добавляю s конец яйца и передумал до того, как завершится отмена, еще один повторяющийся HTTP-пост с поиском яйца не будет сделан.

0 голосов
/ 22 ноября 2018

Вам необходимо использовать оператор debounceTime и switchMap.

this.searchBar.on('change', () => {

    of(this.serachBar.searchText).pipe(
       debounceTime(400),
       distinctUntilChanged(),
       switchMap((text)=> {
          return http.post('api_link', {searchText: text}).map(resp => {
            return resp['Result'];
          });
        });
    ).subscribe(response=> console.log(response));

});
...