RxSwift 实现倒计时

RxSwift 实现倒计时

利用RxSwift 实现倒计时,须要 依靠 takeWhile 来判断为真的条件,不然序列就会一直计时下去 主要代码以下 这么一大坨bash

viewModel.getSMScodeAction.elements.observeOn(MainScheduler.instance).subscribe(onNext: { [weak self](model) in
                guard let self = self else { return }
            self.viewModel.getSMSEableObserable.accept(false)
            let mapResult:Observable<Int> =  Observable<Int>.interval(1, scheduler: MainScheduler.instance).map { (second) -> Int in
                return TOTAL_SECOND - second
            }
            mapResult.takeWhile {
                $0 > 0
            }.subscribe(onNext: { [weak self](remind) in
                guard let self = self else { return }
                self.smsBtn.setTitle("\(remind)s", for: .normal)
                }, onCompleted: {
                    self.smsBtn.setTitle("再次获取", for: .normal)
                    self.viewModel.getSMSEableObserable.accept(true)
            }).disposed(by: self.disposeBag)
            
            
            }, onError: { (error) in
            
            }).disposed(by: disposeBag)
        
复制代码

解释一下

Action

viewModel.getSMScodeAction.elements.observeOn(MainScheduler.instance 返回一个在主线程 上的 Obserable, 订阅它,获得的是,点击 获取验证码,执行网络请求的成功的的 闭包{} ,要在这里去实现 倒计时。 其中 viewModel.getSMScodeAction 是一个 Action Action 是这样的一个类markdown

public final class Action<Input, Element>
复制代码

一个输入,和一个 Element,里面的 elementsAction 的一个属性,是一个 Observable网络

public let elements: Observable<Element>
复制代码

map 、takeWhile

Observable<Int>.interval(1, scheduler: MainScheduler.instance) 是一个 间隔为 1 的 Observable 使用 map 函数,转换成 剩余的时间,类型不变,意义变了闭包

这里的 takeWhile 表示 mapResult 继续执行的条件,倒计时的时间 大于 0 就执行, 不然就停下来,从新获取函数

mapResult.takeWhile {
                $0 > 0
            }.subscribe(onNext: { [weak self](remind) in
                guard let self = self else { return }
                self.smsBtn.setTitle("\(remind)s", for: .normal)
                }, onCompleted: {
                    self.smsBtn.setTitle("再次获取", for: .normal)
                    self.viewModel.getSMSEableObserable.accept(true)
            }).disposed(by: self.disposeBag)
复制代码

注意

takeWhile 的条件不符合的时候,直接终止,走 onCompleted{}, 并不会跳过 当前值spa

例如线程

let disposeBag = DisposeBag()

Observable.of(1, 2, 3, 4, 3, 2, 1)
    .takeWhile { $0 < 4 }
    .subscribe(onNext: { print($0) })
    .disposed(by: disposeBag)

复制代码

到前面的 1,2,3,就终止了 4 后面的不会再输出code

相关文章
相关标签/搜索