Как отменить в полете ожидающие вызовы HTTP API?

У меня есть кнопка на моей веб-странице, при нажатии которой выполняется вызов http api. Требуется некоторое время, чтобы получить ответ и отразить его на странице. Итак, есть ли способ отменить в полете ожидающие HTTP-запросы, чтобы избежать нескольких вызовов API, если пользователь нажимает его несколько раз, что может привести к несогласованности данных?


person SanDash    schedule 08.07.2020    source источник
comment
Вы можете отключить кнопку, пока звонок не вернется   -  person Ale_Bianco    schedule 08.07.2020
comment
Я думал об этом, но это средство выбора даты, и иногда для больших диапазонов дат загрузка данных может занять довольно много времени. Поэтому чувствовал, что лучше переопределить и отменить предыдущие запросы.   -  person SanDash    schedule 08.07.2020


Ответы (3)


Вы когда-нибудь рассматривали сценарий, в котором вам не разрешено отключать кнопку.

В. Что дальше?
А. Пользователь по-прежнему может нажимать кнопку.

Но в таком сценарии вы не хотите делать второй вызов (учитывая, что первый вызов API еще не завершен). ExhaustMap автоматически отменяет второй вызов, если выполняется первый вызов. В этом вся прелесть выхлопной карты.

Для такого сценария используется exhaustMap из RXJS. полезный.

Прочитайте эту замечательную статью, чтобы лучше понять ее

Фиктивный код

fromEvent(this.saveButton.nativeElement, 'click')
    .pipe(
        exhaustMap(() => this.saveCourse(this.form.value))
    )
    .subscribe();

ИЛИ switchMap может быть удобен, когда у вас есть один запрос, и вдруг приходит второй запрос, поэтому он отменяет первый запрос и запускает процесс для второго.

fromEvent(this.saveButton.nativeElement, 'click')
        .pipe(
            swtichMap(() => this.saveCourse(this.form.value))
        )
        .subscribe();

Это зависит от сценария, применимого к вашему приложению.

person micronyks    schedule 08.07.2020
comment
Да, не могу отключить кнопку поиска. Но требование состоит в том, чтобы переопределить первый вызов API и отменить его, а вместо этого сделать второй вызов. Например, кнопка раскрывается, пользовательский интерфейс изменится, и то же самое должно отразиться на ответе API. Я наткнулся на что-то под названием switchMap в RxJS, что может быть более применимо в моем случае. - person SanDash; 08.07.2020
comment
Да, swtichMap может пригодиться для этого. - person micronyks; 08.07.2020

создать атрибут для отключенной кнопки.

isDisabled:boolean=false;

при нажатии меняется на true

this.isDisabled=true;

после того, как вы получили данные в подписке, снова измените значение на false

this.isDisabled=false;

в html привязать его к кнопке

[disabled]="isDisabled"
person pc_coder    schedule 08.07.2020
comment
Спасибо за этот ответ. Я уже пробовал этот подход, но вызовы API могут загружаться довольно долго. Хотя это один из способов, есть ли конкретное решение, как я упомянул, возможно? - person SanDash; 08.07.2020

Вы можете отписаться от запроса:

@Component({ /* ... */ })
export class AppComponent {
  /* ... */
  private request;

  search() {
    if(request){
        request.unsubscribe();
    }

    this.request = this.searchService.search(this.searchField.value)
      .subscribe(
          //...
      );
  }
}
person Ale_Bianco    schedule 08.07.2020