angular - 如果省略了防御性编码/错误检查,则 Angular Observable 订阅失败
问题描述
我正在使用带有 SignalR 的 Angular 8。我正在将一个可观察对象从我的 NotificationService 推送到 DashboardComponent。对于测试,我每 10 秒发送一条测试消息。
如果我在订阅处理程序中省略了一些防御性编码,订阅就会失败——即使实际的通知消息以正确的格式通过,所以在技术上不应该需要它。此外,我从订阅处理程序中收到一条一次性错误消息,该消息似乎在注册订阅时被执行(使用空对象 {})。可能最好用代码解释:
可观察的: (NotificationListenerService)
private doorMessageSource: BehaviorSubject<any> = new BehaviorSubject<any>({});
doorMessage$: Observable<any> = this.doorMessageSource.asObservable();
提升者: (NotificationListenerService)
this.doorMessageSource.next(notificationMessage);
订阅:( 仪表板组件)
constructor(private breakpointObserver: BreakpointObserver, private _router: Router, private _notificationListener: NotificationListenerService) {
this.doorSubscription = this._notificationListener.doorMessage$
.subscribe((notificationMessage) => {
this.handleDoorMessage(notificationMessage);
});
}
处理程序:(订阅失败 - 没有处理后续事件) (仪表板组件)
doorSubscription: Subscription;
private handleDoorMessage(notificationMessage): void {
// Note - This line does not fail even when notificationMessage = {}
var message = notificationMessage.PayloadMessage;
var messageId = notificationMessage.MessageId;
// This line throws a one-off error message on subscription because
// notificationMessage = {} so message = undefined
console.log(message.Timestamp + ' handleDoorMessage: ' + message.Name);
}
处理程序:(工作) (仪表板组件)
doorSubscription: Subscription;
private handleDoorMessage(notificationMessage): void {
var message = notificationMessage.PayloadMessage;
var messageId = notificationMessage.MessageId;
if (message) {
// Executes correctly for my test messages every 10 seconds
console.log(message.Timestamp + ' handleDoorMessage: ' + message.Name);
} else {
// Executes once
console.log('handleDoorMessage ERROR: Message Format Invalid');
}
}
所以,我真的只是想知道这里发生了什么?为什么在注册时使用空对象调用我的订阅处理程序?它是一个错误吗?还有其他人经历过吗?
解决方案
发生这种情况是因为BehaviorSubject
. BehaviorSubject
当订阅者订阅BehaviorSubject
. 实例化时BehaviorSubject
,必须指定初始值。在您的情况下,它是一个空对象(即{}
)。
由于这个原因,您会看到记录了一次性消息。
如果您不希望这种行为,您可以使用Subject
which doesn't remember [它也不想在实例化时具有初始值] 最后发出的值。话虽如此,订阅者将仅接收在订阅实例之后发出的那些值Subject
。
还有一次,可观察管道中发生了异常,可观察对象将处于错误状态,并且无法发出新值。请参阅以下链接:https ://blog.angular-university.io/rxjs-error-handling/
希望能帮助到你。
推荐阅读
- java - 将图像转换为二维数组仅获得左上象限
- php - laravel 显示 404 错误上传到我的域
- opengl - opengl 骨骼/关节动画公式
- python - Python u-Law (MULAW) 波解压为原始波信号
- javascript - 给定一个时区字符串,我如何在 JS 中将日期对象设置为该 TZ
- javascript - 运行多核机器的 express js 应用程序中的全局对象最佳实践
- dart - 将带参数的函数传递给 VoidCallback
- eclipse - apache tomcat 9.x 不适用于 Eclipse 和 Java 10.0.1
- c# - 无法在 .net core 2.1 中读取 HttpContext 正文
- excel - 用于复制工作表的简单 VBA 代码导致“Microsoft Excel 已停止工作”