Angular BehaviorSubject被多次执行

Angular BehaviorSubject被多次执行,angular,behaviorsubject,Angular,Behaviorsubject,我的应用程序使用angular 4,我使用behaviorSubject在组件之间进行通信,一切正常 这是我的密码: export class Globals { loadStudentsByClass: BehaviorSubject<string> = new BehaviorSubject<string>(null); } export class ClassComponent implements OnInit { selectNewClass() {

我的应用程序使用angular 4,我使用behaviorSubject在组件之间进行通信,一切正常

这是我的密码:

export class Globals {
loadStudentsByClass: BehaviorSubject<string> = new BehaviorSubject<string>(null);
}

export class ClassComponent implements OnInit {
selectNewClass() {
    console.log('About to select new class', this.selectedClass);
    this.globals.loadStudentsByClass.next(this.selectedClass); 
    this.globals.changeClassBehavior.next(true);
    this.router.navigateByUrl('');
  }
}

export class StudentComponent implements OnInit {
    this.globals.loadStudentsByClass.subscribe(value => {
          if (!isNullOrUndefined(value) && this.selectedClass !== value) {
            console.log('loadStudentsByClass=> home');
            this.loadStudentsByClass(this.selectedClass);
          }
        });
}
导出类全局变量{
loadStudentsByClass:BehaviorSubject=new BehaviorSubject(空);
}
导出类ClassComponent实现OnInit{
selectNewClass(){
console.log('即将选择新类',this.selectedClass);
this.globals.loadStudentsByClass.next(this.selectedClass);
this.globals.changeClassBehavior.next(true);
这个.router.navigateByUrl(“”);
}
}
导出类StudentComponent实现OnInit{
this.globals.loadStudentsByClass.subscribe(值=>{
如果(!isNullOrUndefined(value)&&this.selectedClass!==value){
log('loadStudentsByClass=>home');
this.loadStudentsByClass(this.selectedClass);
}
});
}
因此,我有一个组件
ClassComponent
,它触发
StudentComponent
调用函数
loadStudentsByClass

这是唯一一个我称之为行为主体的地方,但我发现我的行为主体不止一次被释放

问题在于,尽管
this.globals.loadStudentsByClass.next(this.selectedClass)是this.globals.loadStudentsByClass,但为什么behaviorSubject多次执行
loadStudentsByClass
仅被调用一次


顺便说一句,执行的次数取决于我在应用程序中访问的视图的数量,这将调用两次,因为每当行为主体更改时,它将发出最新的值。以前它是空的(作为默认值),您已经给了它,接下来当服务响应到来时,您正在执行下一个操作,因此它将在更改后发出最新的值,这是足够公平的。对于您的代码,您应该只检查

if(value){// do the stuff here}

尝试没有初始值但仍将缓存流的replay主题:

export class Globals {
loadStudentsByClass = new ReplaySubject<string>(1);
}
导出类全局变量{
loadStudentsByClass=新的ReplaySubject(1);
}

当组件被销毁时,您可能忘记取消订阅StudentComponent。将订阅保存在类变量和
ngondestry()
lifecycle钩子调用
subscription.unsubscribe()

您能否在stackblitz.com上提供更多的代码或更好的演示代码>我知道它被调用了两次(第一次为null,第二次为value),问题发生在第二次出现一个值之后,如果该值相同,则可以调用它两次以上。可能存在这样的用例,即您离开该页面,然后再次访问该页面,因此它可能会被调用,因为即使您离开该页面,您正在进行的订阅仍处于活动状态。为了避免这种情况,您应该执行以下操作:this.mySubscription=this.globals.loadStudentsByClass.subscribe(value=>{if(!isNullOrUndefined(value)&&this.selectedClass!==value){console.log('loadStudentsByClass=>home');this.loadStudentsByClass(this.selectedClass);});Ngondestory(){this.mySubscription.unsubscribe();}我注意到您提到的执行次数取决于我在应用程序中访问的视图的数量。当然,你必须取消订阅,以避免多次订阅。这就是现在正在发生的事情。这可能会在将来导致内存泄漏。最好在angularI的ngOnDestroy()生命周期钩子上取消订阅这样做了,我保存了我的订阅,然后销毁了它,但仍然有相同的问题
ngOnDestroy():void{this.subscription.unsubscribe();}
。我应该销毁所有组件还是仅销毁StudentComponent的订阅一旦组件不在内存中,您应该销毁所有订阅,无论您在哪里订阅;这就是Ngondestry()我做了,但仍然有同样的问题