Aromal Sasidharan
Aromal Sasidharan

Reputation: 678

Recursive calls using RxSwift Observables

I am trying to do a recursive call using 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()

When I comment the delay in above code, the output comes correctly like below

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

with delay the code only outputs

current item is 0
Program ended with exit code: 0

Please help me to understand what happens when the delay is added.

Upvotes: 1

Views: 520

Answers (2)

jboulter11
jboulter11

Reputation: 152

To clarify Daniel T.'s answer, as soon as your code

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

goes out of scope, the subscription is disposed of, which is why you see it without the delay, but adding the delay will end up not executing the rest of the sequence until after it has been disposed of. The class which subscribes to the observable should have a DisposeBag which will retain the subscription when it goes out of scope.

// 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)

When the dispose bag goes out of scope, so will your subscription and it will be disposed of, terminating the sequence emitted.

Upvotes: 0

Daniel T.
Daniel T.

Reputation: 33979

The answer has to do with the environment you are executing this code in. The program calls the observeUntil(initialValue:) function and then exists as soon as that function returns.

Without the delay the function returns after the recursive code is all executed. With the delay the function returns when the delay starts.

Basically, your program ends in less than a second so only "0" is output.

Upvotes: 3

Related Questions