如何在服务请求上使用 switchmap?

mas*_*su9 2 rxjs angular

我有一个表单,其中有一个按钮,可以使用表单的内容发送电子邮件。我想使用 switchmap,因为我想防止用户垃圾点击并创建大量 HTTP 请求,但我不知道该怎么做。

使用 switchmap 之前:

this.customService.sendEmail(this.emailContents).subscribe(
    data => { console.log("Success") }
)
Run Code Online (Sandbox Code Playgroud)

尝试使用 switchmap:

this.customService.sendEmail(this.emailContents).pipe(
    switchMap(() => this.customService.sendEmail(this.emailContents))
)
.subscribe(
    data => { console.log("Success") }
)
Run Code Online (Sandbox Code Playgroud)

但现在,点击按钮 3 次时,它会发送 12 封电子邮件,而不是发送 1 封电子邮件。我认为我在错误的地方使用它,但我真的不知道应该如何使用它......

Deb*_*ahK 5

在你的代码中:

this.customService.sendEmail(this.emailContents).pipe(
    switchMap(() => this.customService.sendEmail(this.emailContents))
)
.subscribe(
    data => { console.log("Success") }
)
Run Code Online (Sandbox Code Playgroud)

您正在多次调用sendEmail...无论是作为外部 Observable 还是在 switchMap 内。

要使用 switchMap,您需要有一个源流……也许是一个与按钮单击事件相关的操作流。然后,您可以sendEmail在 switchMap 中进行调用,如您所示。

您可以这样想... switchMap 需要位于您想要做出反应的操作上...这将是单击。而switchMap内部就是你想要执行你想要限制的操作的地方。

(尽管正如其他人所说,在这种情况下,switchMap 可能不是您的最佳选择,因为它仍然可以处理多个按钮单击,具体取决于操作的速度以及用户继续单击的时间。)

例如:

  clickSubject = new Subject<number>();
  clickAction$ = this.clickSubject.asObservable();

  performAction$ = this.clickAction$.pipe(
    switchMap(item => this.doSomething())
  );

  onClick() {
    this.clickSubject.next();
  }

  doSomething() {
    return interval(500);
  }
Run Code Online (Sandbox Code Playgroud)

更好的选择可能是debounceTime

  performAction$ = this.clickAction$.pipe(
    debounceTime(250),
    switchMap(item => this.doSomething())
  );
Run Code Online (Sandbox Code Playgroud)

在这里查看更完整的示例:https://stackblitz.com/edit/angular-subject-order-deborahk