You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法等待SweetAlert响应,如何等确认/取消后执行后续代码?

问题:SweetAlert确认框未等待用户操作就触发后续逻辑

我有一个点击触发的组件方法:

executeEditUser() {
    this.alertService.confirmationAlertUserEdit();
    
    this.alertService.getBehaviorAlertEvent().subscribe({
        next: (isConfirmed) =>  {
            if (isConfirmed) {
                this.userService.editUser(this.id, this.userModel).subscribe({
                    next: () => this.reloadResources(),
                    error: (err) => this.alertService.errorAlert(err)
                 })
            }   
        },
        error: (err) => this.alertService.errorAlert(err)
    })
}

通过独立的alertService类调用SweetAlert确认对话框(含确认/取消按钮),根据用户操作通过BehaviorSubject触发事件,再由getBehaviorAlertEvent()的订阅处理逻辑。但问题是:对话框弹出后,还未点击确认/取消,后续的订阅代码就已执行。

以下是alertService中的弹窗代码:

confirmationAlertUserEdit() {
    Swal.fire({
        title: 'Confirm user edit?',
        text: "Changes can be made again",
        icon: 'warning',
        showCancelButton: true,
        confirmButtonColor: '#3085d6',
        cancelButtonColor: '#d33',
        confirmButtonText: 'Save edit'
    }).then((result) => {
        if (result.isConfirmed) {
            Swal.fire(
                'Edited!',
                'User edited',
                'success'
            )
            this.behaviorAlertEvent.next(true);
        } else {
            this.behaviorAlertEvent.next(false);
        }
    })
}

解决方案

核心问题分析

问题根源在于BehaviorSubject的特性:它会保留最新的一次事件值,当新的订阅发生时,会立刻把这个旧值推送给订阅者。如果用户之前操作过弹窗,新的订阅会直接触发旧的结果;另外,全局BehaviorSubject容易导致多次订阅的内存泄漏,以及逻辑耦合问题。

方案1:改造弹窗方法返回Observable(推荐)

直接让confirmationAlertUserEdit返回一个Observable,替代全局BehaviorSubject,这样组件可以直接订阅弹窗的操作结果,逻辑更清晰且避免旧值干扰:

修改alertService代码:

import { Observable } from 'rxjs';

// ...

confirmationAlertUserEdit(): Observable<boolean> {
  return new Observable(observer => {
    Swal.fire({
      title: 'Confirm user edit?',
      text: "Changes can be made again",
      icon: 'warning',
      showCancelButton: true,
      confirmButtonColor: '#3085d6',
      cancelButtonColor: '#d33',
      confirmButtonText: 'Save edit'
    }).then((result) => {
      if (result.isConfirmed) {
        Swal.fire('Edited!', 'User edited', 'success');
        observer.next(true);
      } else {
        observer.next(false);
      }
      observer.complete(); // 完成Observable,防止内存泄漏
    }).catch(error => {
      observer.error(error);
      observer.complete();
    });
  });
}

修改组件的executeEditUser方法:

executeEditUser() {
  // 直接订阅弹窗返回的Observable,无需全局Subject
  this.alertService.confirmationAlertUserEdit().subscribe({
    next: (isConfirmed) => {
      if (isConfirmed) {
        this.userService.editUser(this.id, this.userModel).subscribe({
          next: () => this.reloadResources(),
          error: (err) => this.alertService.errorAlert(err)
        });
      }
    },
    error: (err) => this.alertService.errorAlert(err)
  });
}

方案2:改用Subject替代BehaviorSubject(兼容原有逻辑)

如果一定要保留全局事件的方式,将BehaviorSubject替换为普通Subject,因为Subject不会保留历史值,只有订阅后发送的事件才会被接收:

修改alertService中的Subject定义:

import { Subject } from 'rxjs';

// 替换原来的BehaviorSubject
private behaviorAlertEvent = new Subject<boolean>();

getBehaviorAlertEvent(): Observable<boolean> {
  return this.behaviorAlertEvent.asObservable();
}

组件代码调整(可选):

为避免多次订阅内存泄漏,建议在组件销毁时取消订阅:

import { Subscription } from 'rxjs';

private alertSub!: Subscription;

executeEditUser() {
  // 先取消之前的订阅
  if (this.alertSub) {
    this.alertSub.unsubscribe();
  }
  
  this.alertSub = this.alertService.getBehaviorAlertEvent().subscribe({
    next: (isConfirmed) => {
      if (isConfirmed) {
        this.userService.editUser(this.id, this.userModel).subscribe({
          next: () => this.reloadResources(),
          error: (err) => this.alertService.errorAlert(err)
        });
      }
    },
    error: (err) => this.alertService.errorAlert(err)
  });
  
  // 最后调用弹窗
  this.alertService.confirmationAlertUserEdit();
}

// 组件销毁时清理订阅
ngOnDestroy() {
  if (this.alertSub) {
    this.alertSub.unsubscribe();
  }
}

内容的提问来源于stack exchange,提问作者Andrеw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:41:11