我遇到的问题是,每次初始化组件VisOpComponent
时,订阅的事件发射器都会被激发,而不会调用.next()
。我还添加了一些console.log,如下所示,向您展示了这一点,尽管subEvtEmitterOnVisualizeBtnClicked
未初始化,但仍然可以调用事件订阅中的日志语句,并打印subEvtEmitterOnVisualizeBtnClicked called
请告诉我为什么事件在没有任何调用.next()
的情况下被触发,以及如何修复
VisOpComponent:
if(this.subEvtEmitterOnVisualizeBtnClicked) {
if(this.subEvtEmitterOnVisualizeBtnClicked.closed){
console.log("closed subEvtEmitterOnVisualizeBtnClicked")
} else {
console.log("NOT closed subEvtEmitterOnVisualizeBtnClicked")
}
} else {
console.log("subEvtEmitterOnVisualizeBtnClicked not initialized")
}
this.subEvtEmitterOnVisualizeBtnClicked = this._FromAwanti1ToVisOpService.getEmitterOnVisualizeButtonClicked().subscribe((param:number)=>{
console.log("subEvtEmitterOnVisualizeBtnClicked called")
this.visulizationOperationID = param
this.submit()
})
事件发射器:
import { Injectable } from '@angular/core';
import { Component, OnInit, EventEmitter, Output } from '@angular/core';
import { BehaviorSubject, Subject,ReplaySubject } from 'rxjs'
@Injectable({
providedIn: 'root'
})
export class FromAwanti1ToVisOpOfAocAvghInterceptionService {
private emitterOnVisualizeButtonClicked:Subject<number> = new ReplaySubject<number>();
constructor() { }
public emitOnVisualizeButtonClicked(param) {
this.emitterOnVisualizeButtonClicked.next(param)
}
public getEmitterOnVisualizeButtonClicked() {
return this.emitterOnVisualizeButtonClicked.asObservable();
}
日志:
vis-op.component.ts:45 constructor
vis-op.component.ts:59 subEvtEmitterOnVisualizeBtnClicked not initialized
vis-op.component.ts:63 subEvtEmitterOnVisualizeBtnClicked called
如果您绝对确定emitOnVisualizeButtonClicked(param)
从未被调用来触发第63行上不需要的调用,那么您可能需要检查是否有多个订阅正在发生-也许VisOpComponent
是以前构造的,但没有unsubscribe()
?
其他的推理是ReplaySubject本身。当发生新的订阅时,将其添加到容器中,并将缓存中的值(如果有的话(重播给相应的观察者。
你可以添加一个if-guard
this.subEvtEmitterOnVisualizeBtnClicked = this._FromAwanti1ToVisOpService.getEmitterOnVisualizeButtonClicked().subscribe((param:number)=>{
if (!param) return;
console.log("subEvtEmitterOnVisualizeBtnClicked called")
this.visulizationOperationID = param
this.submit()
})
同样重要的是要知道,在向新的后续订阅发送完整或错误错误通知之前,ReplaySubject仍会重播缓存的值。
添加一个new ReplaySubject<number>(1)
的缓冲区大小。如果我们给(1)
,它可以记录和重放一系列的值或最后一个值。