Reactive Swift失败时不完成

问题描述 投票:0回答:1

我有一个功能很不错的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,但是我不想增加很多次,我只希望它继续。

swift reactive-cocoa reactive-swift
1个回答
1
投票

您可以创建自己的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)将停止操作。您应该这样做something,以防止在最坏的情况下永远重试。


0
投票

您可以创建自己的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)将停止操作。您应该这样做something,以防止在最坏的情况下永远重试。

© www.soinside.com 2019 - 2024. All rights reserved.