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

时间:2019-11-14 20:47:59

标签: angular rxjs

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

在使用switchmap之前:

this.customService.sendEmail(this.emailContents).subscribe(
    data => { console.log("Success") }
)

尝试使用switchmap:

this.customService.sendEmail(this.emailContents).pipe(
    switchMap(() => this.customService.sendEmail(this.emailContents))
)
.subscribe(
    data => { console.log("Success") }
)

但是现在单击3次按钮时,它将发送12封电子邮件,而不是发送1封电子邮件。我想我在错误的地方使用了它,但是我并没有真正看到我应该如何使用它...

1 个答案:

答案 0 :(得分:2)

在您的代码中:

this.customService.sendEmail(this.emailContents).pipe(
    switchMap(() => this.customService.sendEmail(this.emailContents))
)
.subscribe(
    data => { console.log("Success") }
)

您多次呼叫sendEmail ...作为外部Observable以及在switchMap内。

要使用switchMap,您需要有一个源流...也许是一个与您的按钮单击事件相关联的动作流。然后,如图所示,在switchMap中调用sendEmail

您可以这样想... 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);
  }

更好的选择可能是debounceTime

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

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