如何在RxSwift中按顺序循环observable?

时间:2017-02-08 14:35:25

标签: swift reactive-programming rx-swift

我正在尝试创建一个轮询网络服务的流。此时它会查询服务,然后在短暂延迟后完成。我希望继续进行重新启动而不是完成,从而永远轮询服务。

你可以做点像......

myPollingStream.repeat()

但是RxSwift中的repeat实际上是repeatElement,因此实际上生成了一个可观察的流。您可以concatMap将这些变为扁平的序列序列,但RxSwift没有concatMap运算符。

那么如何在RxSwift中循环一个observable?

我希望请求是顺序的,而不是并发的,因此flatMap不是一个选项,因为它合并了导致重叠请求的流。我正在寻找与retry()的工作方式类似的内容,但重新启动onComplete而不是onError

2 个答案:

答案 0 :(得分:5)

Observable.repeatElement(myPollingStream, scheduler: MainScheduler.instance).concat()
  • repeatElement(_:scheduler:)将创建无限的轮询查询流。
  • contat()将确保在订阅下一个查询之前完成每个轮询查询。

注意

虽然上述方法在理论上有效,但没有背压实现,repeatElements(_:scheduler:)将发出事件,直到最终耗尽内存。这使得此解决方案不适用于RxSwift 3.0。有关详细信息,请参阅RxSwift存储库中的this issue

答案 1 :(得分:0)

选项1:递归函数

您的myPollingStream

func myPollingStream() -> Observable<Result> { 
    return Observable<String>.create { observer in
        // your network code here


        return Disposables.create()
    }
}

然后创建一个递归函数:

func callMyPollingStream() {
    myPollingStream()
        .subscribe(onNext: { result in
            callMyPollingStream() // when onNext or onCompleted, call it again 
        })
        .addDisposableTo(db)
}

选项2:使用间隔

let _ = Observable<Int>
            .interval(5, scheduler: MainScheduler.instance)
            .subscribe(onNext: { _ in
                let _ = myPollingStream().subscribe()
            })
            .addDisposableTo(db)

使用此选项,myPollingStream()函数将每5秒调用一次。