首页 > 解决方案 > 如何使用switchMap取消http请求?

问题描述

如果我向服务器发出新的 http 请求,我想取消以前的 http 请求,但它没有按预期工作。

如果函数中的某些值发生更改,我想取消请求我的意思是如果值更改旧请求应该取消并且应该为此创建新请求,我已经这样做了

1) 创建了一个主题 - 将由observable
public stringVar = new Subject<string>();

2) 创建一个 observable 来观察主题并发送更新流(您将订阅它以获取更新流)

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”发生更改,我想取消我的旧请求并创建新请求。

标签: angularhttprxjsobservableswitchmap

解决方案


我相信testResult(selectedValue)每当您单击按钮时都会调用您的方法,因此这将创建新的 Observable 并在您单击按钮并调用方法时订阅它。这些新的 Observable 订阅导致了多个网络请求。

理想情况下,您希望stringVar$在构造函数中仅订阅一次,stringVar并且当某些内容发生更改时,只需在Subject中发出更新的值。由于 Observable 订阅只是一个并且已经存在,它将捕获发出的新值并在switchMap操作员的帮助下创建新的 http 请求。

仅供参考,您选择了正确的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);
  }
}

推荐阅读