代码之家  ›  专栏  ›  技术社区  ›  Renaud is Not Bill Gates

为什么subscribe函数中的代码执行多次

  •  0
  • Renaud is Not Bill Gates  · 技术社区  · 5 年前

    我为我的应用程序创建了一个通知服务,如下所示:

    export class NotificationService {
      private subject = new Subject<Notification>();
    
      constructor() {}
    
      getNotification(): Observable<any>{
        return this.subject.asObservable();
      }
    
      success(title: string, message: string){
        this.notif(NotificationType.SUCCESS, title, message);
      }
    
      error(title: string, message: string){
        this.notif(NotificationType.ERROR, title, message);
      }
    
      technicalError(title:string, message: string){
        this.notif(NotificationType.TECHNICAL_ERROR, title, message);
      }
    
      info(title: string, message: string){
        this.notif(NotificationType.INFO, title, message);
      }
    
      warning(title: string, message: string){
        this.notif(NotificationType.WARNING, title, message);
      }
    
      notif(type: NotificationType, title: string, message: string){
        this.subject.next(<Notification>{ type: type, title: title, message: message});
      }
    

    下面是我如何使用此服务的示例:

    this.notificationService.success("Suppression", "L'enregistrement a été supprimée !");
    

    由于我有一个在所有组件之间共享的组件,即头部,所以我在它的ngoninit函数中有一个通知服务主题的订阅:

    this.notificationService.getNotification().subscribe((notification: Notification) => {
          this.notification.create(NotificationType[notification.type], notification.title, notification.message);
        });
    

    第一次运行应用程序时,当我调用某个notificationservice函数时,subscribe函数内的代码执行一次,但之后subscribe函数内的代码执行多次。

    我怎么解决这个问题?

    2 回复  |  直到 5 年前
        1
  •  2
  •   Alex K    5 年前

    每次创建头组件的实例时,都会创建对通知服务的另一个订阅。当头组件被销毁时,它必须清除其订阅。如果没有,订阅块将在Observable发出新值时继续执行。

    一般来说,订阅服务的任何组件都应该包含一个ngonDestroy生命周期方法,用于清除它所做的任何订阅。

    要自动取消订阅,可以使用 componentDestroyed 主题和RXJS takeUntil 操作员。在NgonDestroy中,您在 组件已销毁 完成订阅:

    export class HeaderComponent implements OnInit, OnDestroy {
      private componentDestroyed = new Subject<any>();
    
      constructor(private notificationService: NotificationService) { }
    
      ngOnInit() {
        this.notificationService.getNotification()
          .pipe(takeUntil(this.componentDestroyed))
          .subscribe(notification => {
            // ...
          });
      }
    
      ngOnDestroy() {
        this.componentDestroyed.next();
      }
    }
    

    Here's a StackBlitz example.

        2
  •  0
  •   SiddAjmera    5 年前

    你在打电话给 notif 其他方法的方法,如 success , error , info , warning 等等 诺蒂夫 方法正在调用 next 对你 Subject 它最终将一个新的价值推到 主体 你作为一个 Observable 通过调用 asObservable() 方法。

    确保您没有致电 成功 , 错误 , 信息 , 警告 等等,在你的应用程序中的任何地方。如果这些方法被多次调用,则 subscribe 方法也将被多次调用。