RxSwift 中的倒计时

1,157 阅读1分钟

在使用 RxSwift 的工程中,没有发现倒计时的功能,于是自己实现了一个:

/// 倒计时
/// - Parameters:
///   - second: 倒计时的秒数
///   - immediately: 是否立即开始,true 时将立即开始倒计时,false 时将在 1 秒之后开始倒计时
///   - duration: 倒计时的过程
/// - Returns: 倒计时结束时的通知
func countdown(second: Int,
               immediately: Bool = true,
               duration: ((Int) -> Void)?) -> Single<Void> {
    guard second > 0 else {
        return Single<Void>.just(())
    }

    if immediately {
        duration?(second)
    }
    return Observable<Int>
        .interval(RxTimeInterval.seconds(1), scheduler: MainScheduler.instance)
        .map { second - (immediately ? ($0 + 1) : $0) }
        .take(second + (immediately ? 0 : 1))
        .do(onNext: { (index) in
            duration?(index)
        })
        .filter { return $0 == 0 }
        .map { _ in return () }
        .asSingle()
 }

使用的方法为:

debugPrint(Date())
countdown(second: 5) { (index) in
    debugPrint(Date())
    debugPrint("倒计时:\(index)")
}
.subscribe(onSuccess: { () in
    debugPrint(Date())
    debugPrint("倒计时结束")
}) { (error) in
    debugPrint("倒计时错误:\(error)")
}
.disposed(by: disposeBag)

输出:

2020-09-08 08:58:06 +0000
2020-09-08 08:58:06 +0000
"倒计时:5"
2020-09-08 08:58:07 +0000
"倒计时:4"
2020-09-08 08:58:08 +0000
"倒计时:3"
2020-09-08 08:58:09 +0000
"倒计时:2"
2020-09-08 08:58:10 +0000
"倒计时:1"
2020-09-08 08:58:11 +0000
"倒计时:0"
2020-09-08 08:58:11 +0000
"倒计时结束"