使用 RxSwift 的反应式异步反馈系统
Reactive asynchronous feedback system with RxSwift
我正在 RXSwift (ReactiveX) 的帮助下设计一个呼叫管理器,它持续与 API 交互。呼叫管理器包含几个对象,这些对象本身包含 indicator
(指示从 API 加载的状态信息)和 control
(要发送到 API 的请求)。
class CallManagerObjectA() {
var control = PublishSubject<String>()
var indicator = BehaviorSubject<String>(value: "string status")
}
在呼叫管理器中,调度程序定期向可观察指标提供新值:
<... API response ...>
indicator.onNext(newValue)
视图控制器中的其他地方,将观察标签的指示器:
indicator.subscribe(onNext: { label.stringValue = [=12=] })
在同一个视图控制器中,用户可以通过 GUI 元素连续控制对象状态:
control.onNext(commandValue)
在调用管理器中,将观察到 API 调用的控件:
control.subscribe(onNext: { (command) in
// API request call
})
到目前为止一切顺利,这在响应式模式下运行得非常好。
现在,如果呼叫管理器在 API 交互过程中识别出错误并在视图控制器中向用户显示这些错误,我正在寻找一个很好的错误处理解决方案。我立刻想到了这样的事情:
// Call manager recognizes the error
control.onError(error)
...
// Call manager ignores errors for the subscriber
control.retry().ignoreErrors().subscribe(onNext: { (command) in
// API request call
})
...
// View controller shows the errors
indicator.subscribe(onNext: { label.stringValue = [=15=] })
control.subscribe(onError: { print("error", [=15=]) })
然而,这最终陷入无限循环。
我担心我对反应式编程有一个基本的理解问题,或者我错过了一些非常重要的东西,但我无法理解在这种反应式模式环境中如何处理错误。
根据您展示的代码,您有很大的误解,不仅是关于如何处理错误,而且对于一般情况下如何进行反应式编程。尝试观看此视频“Reactive Programming: Why It Matters”
具体回答你的问题,这里有两个误区:
当您拨打 control.onError(_:)
时,这将是您在 control
上可以拨打的最后一个电话。一旦它发出错误,它将停止工作。
retry()
运算符向 "try again on Error" 询问其来源。如果它的来源是确定的,那么它只会做它之前做的完全相同的事情并发出完全相同的输出(即,它上次发出的相同错误。)在 PublishSubject
的情况下,它不会不知道为什么调用 onError。所以它能做的最好的就是再次发出错误。
老实说,我认为这是 API 中的一个错误,因为订阅过去某个时候发出错误的发布主题应该什么都不做。但是,你不会问为什么你有一个无限循环。相反,您会问为什么 control
停止发出事件。
我正在 RXSwift (ReactiveX) 的帮助下设计一个呼叫管理器,它持续与 API 交互。呼叫管理器包含几个对象,这些对象本身包含 indicator
(指示从 API 加载的状态信息)和 control
(要发送到 API 的请求)。
class CallManagerObjectA() {
var control = PublishSubject<String>()
var indicator = BehaviorSubject<String>(value: "string status")
}
在呼叫管理器中,调度程序定期向可观察指标提供新值:
<... API response ...>
indicator.onNext(newValue)
视图控制器中的其他地方,将观察标签的指示器:
indicator.subscribe(onNext: { label.stringValue = [=12=] })
在同一个视图控制器中,用户可以通过 GUI 元素连续控制对象状态:
control.onNext(commandValue)
在调用管理器中,将观察到 API 调用的控件:
control.subscribe(onNext: { (command) in
// API request call
})
到目前为止一切顺利,这在响应式模式下运行得非常好。 现在,如果呼叫管理器在 API 交互过程中识别出错误并在视图控制器中向用户显示这些错误,我正在寻找一个很好的错误处理解决方案。我立刻想到了这样的事情:
// Call manager recognizes the error
control.onError(error)
...
// Call manager ignores errors for the subscriber
control.retry().ignoreErrors().subscribe(onNext: { (command) in
// API request call
})
...
// View controller shows the errors
indicator.subscribe(onNext: { label.stringValue = [=15=] })
control.subscribe(onError: { print("error", [=15=]) })
然而,这最终陷入无限循环。 我担心我对反应式编程有一个基本的理解问题,或者我错过了一些非常重要的东西,但我无法理解在这种反应式模式环境中如何处理错误。
根据您展示的代码,您有很大的误解,不仅是关于如何处理错误,而且对于一般情况下如何进行反应式编程。尝试观看此视频“Reactive Programming: Why It Matters”
具体回答你的问题,这里有两个误区:
当您拨打
control.onError(_:)
时,这将是您在control
上可以拨打的最后一个电话。一旦它发出错误,它将停止工作。retry()
运算符向 "try again on Error" 询问其来源。如果它的来源是确定的,那么它只会做它之前做的完全相同的事情并发出完全相同的输出(即,它上次发出的相同错误。)在PublishSubject
的情况下,它不会不知道为什么调用 onError。所以它能做的最好的就是再次发出错误。
老实说,我认为这是 API 中的一个错误,因为订阅过去某个时候发出错误的发布主题应该什么都不做。但是,你不会问为什么你有一个无限循环。相反,您会问为什么 control
停止发出事件。