不要在 Reactive 中失败时完成 Swift
Dont complete on fail in Reactive Swift
我有一个从 api 捕获事件的函数,效果很好。唯一的问题是我不希望流在失败时完成。
public func getDeviceEvent(deviceUID: String) -> SignalProducer<DeviceEvent, HTTPConnectorError> {
return SignalProducer<DeviceEvent, HTTPConnectorError> { observer, _ in
self.getDeviceEvent(deviceUID: deviceUID) { result in
switch result {
case .success(let deviceEvent):
observer.send(value: deviceEvent)
observer.sendCompleted()
case .failure(let error):
observer.send(error: error)
}
}
}
}
private func getDeviceEvent(deviceUID: String, completion: @escaping (Result<DeviceEvent, HTTPConnectorError>) -> Void) {
httpConnector.request(authenticated: true, target: .deviceLocationEvent(deviceID: deviceUID), parse: makeParser(), completion: completion)
}
有什么方法可以让直播继续进行吗?我知道有 retry
但我不想添加很多次我只是希望它继续。
您可以创建自己的 retry
版本,它会无限期地重试(我在此处提供了一个版本,它在每次失败后暂停一段给定的时间间隔):
extension SignalProducer {
func retry() -> SignalProducer<Value, Never> {
flatMapError { _ in
self.retry()
}
}
func retry(interval: TimeInterval, on scheduler: DateScheduler) -> SignalProducer<Value, Never> {
flatMapError { _ in
SignalProducer<Value, Never>.empty
.delay(interval, on: scheduler)
.concat(self.retry(interval: interval, on: scheduler))
}
}
}
然后您可以使用 on(failed:)
在每次失败时向用户显示一些内容,同时无限期地重试:
getDeviceEvent(deviceUID: someDeviceUID)
.on(failed: { error in
print(error)
// Display this to the user
})
.retry(interval: 1.0, on: QueueScheduler())
.take(during: self.lifetime)
.startWithValues { value in
print(value)
}
此代码片段假定 self
是一个视图控制器; take(during: self.lifetime)
将在当前视图控制器解除分配时停止操作。你应该像这样做一些事情,以防止在最坏的情况下永远重试。
我有一个从 api 捕获事件的函数,效果很好。唯一的问题是我不希望流在失败时完成。
public func getDeviceEvent(deviceUID: String) -> SignalProducer<DeviceEvent, HTTPConnectorError> {
return SignalProducer<DeviceEvent, HTTPConnectorError> { observer, _ in
self.getDeviceEvent(deviceUID: deviceUID) { result in
switch result {
case .success(let deviceEvent):
observer.send(value: deviceEvent)
observer.sendCompleted()
case .failure(let error):
observer.send(error: error)
}
}
}
}
private func getDeviceEvent(deviceUID: String, completion: @escaping (Result<DeviceEvent, HTTPConnectorError>) -> Void) {
httpConnector.request(authenticated: true, target: .deviceLocationEvent(deviceID: deviceUID), parse: makeParser(), completion: completion)
}
有什么方法可以让直播继续进行吗?我知道有 retry
但我不想添加很多次我只是希望它继续。
您可以创建自己的 retry
版本,它会无限期地重试(我在此处提供了一个版本,它在每次失败后暂停一段给定的时间间隔):
extension SignalProducer {
func retry() -> SignalProducer<Value, Never> {
flatMapError { _ in
self.retry()
}
}
func retry(interval: TimeInterval, on scheduler: DateScheduler) -> SignalProducer<Value, Never> {
flatMapError { _ in
SignalProducer<Value, Never>.empty
.delay(interval, on: scheduler)
.concat(self.retry(interval: interval, on: scheduler))
}
}
}
然后您可以使用 on(failed:)
在每次失败时向用户显示一些内容,同时无限期地重试:
getDeviceEvent(deviceUID: someDeviceUID)
.on(failed: { error in
print(error)
// Display this to the user
})
.retry(interval: 1.0, on: QueueScheduler())
.take(during: self.lifetime)
.startWithValues { value in
print(value)
}
此代码片段假定 self
是一个视图控制器; take(during: self.lifetime)
将在当前视图控制器解除分配时停止操作。你应该像这样做一些事情,以防止在最坏的情况下永远重试。