使用RxSwift Observables进行递归调用

时间:2019-11-19 11:20:15

标签: ios swift rx-swift

我正在尝试使用RxSwift Observables进行递归调用。

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)
                    .flatMapLatest{observeUntil(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

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

2 个答案:

答案 0 :(得分:3)

答案与您在其中执行此代码的环境有关。该程序调用{​​{1}}函数,然后在该函数返回时立即存在。

在没有observeUntil(initialValue:)的情况下,该函数将在递归代码全部执行后返回。使用delay时,函数将在延迟开始时返回。

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

答案 1 :(得分:0)

尽快澄清代码,以澄清Daniel T.的答案

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

超出范围,预订已被处理,这就是为什么您看到它没有延迟的原因,但是加上延迟将导致直到执行完毕后才执行序列的其余部分。预订可观察对象的类应该有一个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)

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