【问题标题】:RAC 4 Swift Failed methodRAC 4 Swift 失败的方法
【发布时间】:2015-11-11 07:23:07
【问题描述】:

ReactiveCocoa 4 在 SignalProducer 类上有一个方法 then 等待生产者完成并用另一个生产者替换它,如下所示:

someProducer.then(replacementProducer).

但是我想要的是一种方法,它等到原始生产者出错,然后用第二个生产者替换它(对完成事件不做任何事情)。

then 实现为(注意不转发下一个事件):

public func then<U>(replacement: SignalProducer<U, Error>) -> SignalProducer<U, Error> {
    let relay = SignalProducer<U, Error> { observer, observerDisposable in
        self.startWithSignal { signal, signalDisposable in
            observerDisposable.addDisposable(signalDisposable)

            signal.observe { event in
                switch event {
                case let .Failed(error):
                    observer.sendFailed(error)
                case .Completed:
                    observer.sendCompleted()
                case .Interrupted:
                    observer.sendInterrupted()
                case .Next:
                    break
                }
            }
        }
    }
    return relay.concat(replacement)
}

除了失败之外,我想要的看起来很相似,它不会发送错误,而是发送完成的信号。更具体地说,switch 语句将更改为:

signal.observe { event in
    switch event {
        case .Failed:
            observer.sendCompleted()
        case .Completed, .Next: break
        case .Interrupted:
            observer.sendInterrupted()
        }
    }
}

我的问题如下:

1) 这有效吗?它按我的预期工作,替换信号仅在第一个信号出错时启动。 2) 有没有更好的方法让错误信息不丢失?

我会使用它的一个例子是两步验证过程:

self.verifyToken(token).failed(self.revalidateSession())

如果令牌验证成功,则一切正常,无需重新验证。如果失败,则需要重新验证。

编辑:

我更改了信号观察块,以便如果第一个信号完成且没有错误,它会以 startWithComplete 开始替换信号,以便完成事件沿链向下转发,而不会触发信号的任何操作。

这样做很容易:

self.verify(token).failed(self.refreshSession(token)).then(self.fetchUserForToken(token))

其中then 被链接,并且仅在verifyrefreshSession 成功时执行。

signal.observe { event in
    switch event {
        case .Failed:
            observer.sendCompleted()
        case .Completed:
            replacement.startWithCompleted {}
        case .Next: break
        case .Interrupted:
            observer.sendInterrupted()
        }
    }
}

【问题讨论】:

    标签: swift reactive-cocoa


    【解决方案1】:

    1) 这有效吗?

    没有。如果您的验证信号生成器发送一个正常值并完成,您的替换信号生成器确实会启动(通过startWithCompleted 调用)但不会产生任何结果(因为您在startWithCompleted 闭包和内部replay 中没有观察到任何东西信号生产者永远不会终止)。

    2) 有没有更好的方法?

    你可以使用flatMapError操作符,这样你也可以得到错误信息。

    self.verify(token)
        .map { _ in () }
        .flatMapError { error in
            return self.refreshSession(token).map { _ in () }
        }
    

    注意,如果veriy 生产者和refreshSession 生产者产生相同类型的值,则可以省略这两个map { _ in () }

    【讨论】:

    • 那么我可以简单地使用mapflatMapError 重写我的failed 方法吗?
    • 取决于是否还要观察原始信号生产者的成功信号
    猜你喜欢
    • 2017-11-05
    • 2021-08-12
    • 2019-09-08
    • 2018-03-12
    • 2018-05-12
    • 1970-01-01
    • 1970-01-01
    • 2018-05-13
    • 2019-09-23
    相关资源
    最近更新 更多