使用 RxSwift Observables 进行递归调用

Posted

技术标签:

【中文标题】使用 RxSwift Observables 进行递归调用【英文标题】:Recursive calls using RxSwift Observables 【发布时间】:2019-11-19 11:20:15 【问题描述】:

我正在尝试。

import RxSwift

func observeUntil(initialValue: Int) -> Observable<Int> 

    return Observable.deferred 
        .just(initialValue)
    
    .do(onNext: 
        print("current item is", $0)
    )
        .flatMapLatest (item) -> Observable<Int> in
            if item < 5 
                return Observable.just(item)
                    //                    .delay(.seconds(1), scheduler: MainScheduler.instance)
                    .flatMapLatestobserveUntil(initialValue: $0 + 1)
             else 
                return .just(item)
            
    

_ = observeUntil(initialValue: 0)
    .subscribe()

当我在上面的代码中注释延迟时,输出正确,如下所示

current item is 0
current item is 1
current item is 2
current item is 3
current item is 4
current item is 5
Program ended with exit code: 0

延迟代码只输出

current item is 0
Program ended with exit code: 0

请帮助我了解添加延迟后会发生什么。

【问题讨论】:

我猜你是在操场上做这个? 使用 SPM 的纯 Swift 项目。 【参考方案1】:

答案与您执行此代码的环境有关。程序调用observeUntil(initialValue:) 函数,然后在该函数返回时立即存在。

没有delay,函数在递归代码全部执行后返回。使用delay,函数在延迟开始时返回。

基本上,您的程序会在不到一秒的时间内结束,因此只输出“0”。

【讨论】:

我只是在 VSCode 中使用 swift 和 SPM 并使用“swift run”执行代码。该项目只是一个 SPM 项目【参考方案2】:

为了澄清 Daniel T. 的答案,只要你的代码

_ = observeUntil(initialValue: 0)
.subscribe()

超出范围,订阅已被处置,这就是为什么您没有延迟看到它的原因,但添加延迟最终会导致在其被处置之前不执行序列的其余部分。订阅 observable 的类应该有一个DisposeBag,它会在订阅超出范围时保留订阅。

// As an instance variable in your class, or some other place you want to retain the subscription
let disposeBag = DisposeBag()

// Where you subscribe
observeUntil(initialValue: 0)
.subscribe()
.disposed(by: myClass.disposeBag)

当处置包超出范围时,您的订阅也会被处置,并终止发出的序列。

【讨论】:

以上是关于使用 RxSwift Observables 进行递归调用的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift - 来自 Singleton 的不同类型的队列 observables

RxSwift - 递归 Observables?

RxSwift 结合异构的 observables

创建 observables 数组后在 RxSwift 中使用 zip 运算符

RxSwift 合并不同类型的 Observables

RxSwift 跟踪多个 observables 活动