Как отменить http-запрос с помощью switchMap? - PullRequest
2 голосов
/ 09 июля 2019

Я хочу отменить предыдущий http-запрос, если я сделал новый http-запрос к серверу, но он не работает, как ожидалось.

Я хочу отменить запрос, если в функции было изменено какое-то значениея имею в виду, что если значение изменилось, старый запрос должен быть отменен, и новый должен быть создан для этого, я сделал это 1) // Создал тему - вещь, за которой будет наблюдать наблюдаемая public stringVar = new Subject ();2) // Создаем заметку для наблюдения за темой и рассылаем поток обновлений (вы подпишитесь на него, чтобы получить поток обновлений) public stringVar $ = this.stringVar.asObservable ()

3) Вопределенная функция, я получаю значение в качестве аргумента, поэтому я выполняю эти шаги

  testFunction(value){
      this.stringVar.next(listValueSelected);
      this.testOutput = this.stringVar$.pipe(
             switchMap(() => {
                return  this.teseService.getEntries(val_one, val_two,val_three);
           })
         )
         this.testOutput.subscribe(result => console.log(`${result}`));
    } 

Запрос отменяется, когда значение собирается измениться, но странное поведение меняется в первый раз, когда только один запрос является режимом, но когда янажмите второй раз, когда он вызывает API два раза, и это будет продолжаться. Что не так с моим кодом?

в component.ts

export class TestComponent {
    testOutput :Observable<any>;
    stringVar =  new Subject<number>();
    stringVar$ = this.stringVar.asObservable();

 testResult(selectedValue) {
       this.stringVar.next(selectedValue);
       this.stringVar$.subscribe(data => {
      });
       this.testOutput = this.stringVar$.pipe(
             switchMap(() => {
                return  this.testService.getTestEntries(this.x,this.y,this.z);
           })
         )
         this.testOutput.subscribe(result => console.log(`${result}`));
    }

}

в служебном файле

getTestEntries(x, y,selectedValue): Observable<any>{
        let apiUrl = selectedValue=='3'?this.baseUrl1:this.baseUrl ;

        return this.http.post(apiUrl,obj).map((response: Response) => {

              return response;
        })
      }

Я хочу отменить мой старый запрос и создать новый, если в компоненте изменилось значение selectedValue.

1 Ответ

2 голосов
/ 09 июля 2019

Я полагаю, что вы вызываете свой метод testResult(selectedValue) всякий раз, когда нажимаете кнопку, так что это создаст новую Наблюдаемую и подпишется на нее, когда вы нажимаете кнопку и вызываете метод. Эти новые подписки Observable вызывают несколько сетевых запросов.

В идеале вы хотите подписаться на stringVar$ только один раз в конструкторе , а когда что-то меняется, просто выдать обновленное значение в stringVar Subject. Поскольку подписка Observable только одна и уже существует, она будет перехватывать выбранное новое значение и создаст новый http-запрос с помощью оператора switchMap.

К вашему сведению, вы правильно выбрали switchMap оператора. Это откажется последний сетевой вызов, если в это время приходит новое событие.

Это ваш рабочий пример:

export class TestComponent {
  testOutput: Observable<any>;
  stringVar = new Subject<number>();
  stringVar$ = this.stringVar.asObservable();

  constructor() {
    this.testOutput = this.stringVar$.pipe(
      switchMap(() => {
        return this.testService.getTestEntries(this.x, this.y, this.z);
      }),
    );
    this.testOutput.subscribe((result) => console.log(`${result}`));
  }

  testResult(selectedValue) {
    this.stringVar.next(selectedValue);
  }
}
...