rxjs可以阻擋button重複點擊造成的api重複邀請嗎?

平常這種情況,我都是用backdrop+spinner之類的東西,去讓整個畫面被擋住,或是在response回來之前disable button,讓使用者不可以按下個按鈕進行操作。

但想知道或許rxjs的設定是不是可以阻擋重複call的動作。可以的話又是否可以立即停止前一個request,直接變成等待最後一個response回來。

我也在尋找這方法
你說的是像這樣?

 // 登入
  LoginUI() {
   
    this.loginService
      .loginAuthorizeUser$Json({ body: this.loginForm.value })
      .subscribe({
        next: (res: any) => {      
        },
      complete: (res: any) => {      
        },
        error: (err: any) => {
      });
  }

還是??

中的 takeUntil

我到目前去擋短時間內的重複發送需求的做法是做一個directive

debounce-click.directive.ts

import {
  Directive,
  HostListener,
  OnInit,
  Output,
  EventEmitter,
  OnDestroy,
  Input,
} from '@angular/core';
import { Subject, Subscription } from 'rxjs';
import { debounceTime } from 'rxjs/operators';

@Directive({
  selector: '[appDebounceClick]',
})
export class DebounceClickDirective implements OnInit, OnDestroy {
  @Input() debounceTime = 500;
  @Output() debounceClick = new EventEmitter();
  private clicks = new Subject();
  private subscription: Subscription;

  constructor() {}

  ngOnInit() {
    this.subscription = this.clicks
      .pipe(debounceTime(this.debounceTime))
      .subscribe(e => this.debounceClick.emit(e));
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }

  @HostListener('click', ['$event'])
  clickEvent(event) {
    event.preventDefault();
    event.stopPropagation();
    this.clicks.next(event);
  }
}

app.modules.ts

import { DebounceClickDirective } from './.......'

@NgModule({
  declarations: [
   ...
  DebounceClickDirective,
 ],

然後在html中

  <button  appDebounceClick   (debounceClick)="myFunction()"
              >執行
              </button>

希望有其他大神給出答案或其他做法

1個讚

有兩種方式

  1. 打 api 都使用 switchMap,這樣只要前一個 request 還沒回來,就會被取消,然後重發一次。
  2. 使用 debounceTime,等於間隔內沒動作,才會發出值,然後才去打 api。

兩種方式稍微不太一樣,第一種是會被一直取消和重打 api,第二種是 n 秒內沒按 button 才會發出 api。

1個讚

或是使用 exhaustMap 也可以做到這個效果,跟 switchMap 的效果不太一樣
exhaustMap: 只認第一次發起的 request
switchMap; 只認最後一次發起的 request

3個讚

感謝大神!我想要的應該是第一種方法!!

我想要的應該是switchMap,謝謝大神回覆!

1個讚