首页 > 解决方案 > 关于 Observable 的条件句的问题。(RxSwift)

问题描述

我尝试创建一个runsample()使用多个可观察对象的函数,如下所示。
如果我在流中间满足特定条件,我想从函数的开头开始。
foo1()在下面的例子中)

在这种情况下,如何修改runsample()功能?

class SampleClass {
    ////////////////////////////////
    // private
    ////////////////////////////////
    private func foo1() -> Observable<String> {
        // Do something
        return .just("TEST")
    }
    
    private func foo2() -> Observable<Bool> {
        // Do something
        return .just(false) // or true
    }
    
    private func foo3() -> Observable<String> {
        // Do something
        return .just("Result")
    }
    
    ////////////////////////////////
    // public
    ////////////////////////////////
    public func runSample() -> Observable<String> {
        return Observable.just(())
            .flatMap { [unowned self] _ in
                self.foo1()
            }
            .flatMap { [unowned self] _ in
                self.foo2()
            }
            // I want to retry foo1() when foo2() is false
            // I want to make foo3() run only if foo2() is true.
            .flatMap { [unowned self] _ in
                self.foo3()
            }
    }
}

标签: swiftrx-swift

解决方案


根据您的评论,这就是您想要的:

func runSample() -> Observable<String> {
    struct NotValid: Error { }
    return Observable.deferred {
        foo1().flatMap { _ in
            foo2().do(onNext: { isValid in
                if !isValid { throw NotValid() }
            })
        }
    }
    .retry()
    .flatMap { _ in foo3() }
}

这是一个非常奇怪的要求,但它是可行的。我希望这是一个XY 问题


你真的要重试foo1() 吗?这意味着它失败了,但显然没有。无论如何,这将做你想要的:

func runSample() -> Observable<String> {
    foo1()
        .flatMap { [foo2] _ in
            foo2()
        }
        .flatMap { [foo1, foo3] isTrue in
            isTrue ? foo3() : foo1()
        }
}

这个函数将返回一个 Observable。每次订阅 Observable 时,foo1()都会激活第一个。

每次第一个foo1()发出一个值时,该值将被忽略(这很奇怪)并被foo2()调用。这将生成一个新的 Observable 将被订阅。

每当通过发出一个值生成的任何 Observables 时foo2(),如果该值为 truefoo3()将被调用,否则foo1()将被调用。无论调用哪一个,它的 Observable 都会被订阅。

整个函数将发出任何 foo1()s 或 foo3()s Observables 发出的所有值。

对于此示例而言,重要的是,您不需要以Observable.just(()).


考虑一下,我更喜欢这样的东西:

func runSample() -> Observable<String> {
    Observable.zip(foo1(), foo2())
        .flatMap { $0.1 ? foo3() : .just($0.0) }
}

这样我就不用跑foo1()两次了。


推荐阅读