07.RxSwift 高階函數(shù)(Driver)

  1. 首先我們創(chuàng)建一個:序列的中的序列 - string - 映射 - 序列,并且發(fā)起多次訂閱,如下代碼:
//創(chuàng)建序列
let result  = inputTF.rx.text.skip(1)
            .flatMap { [weak self](input) -> Observable<Any> in
                return (self?.dealwithData(inputText:input ?? ""))!
        }

//連續(xù)訂閱兩次
        result.subscribe(onNext: { (element) in
            print("訂閱到了--:\(element)")
        })
        result.subscribe(onNext: { (element) in
            print("訂閱到了--:\(element)---\(Thread.current)")
        })

//模擬網(wǎng)絡(luò)請求
func dealwithData(inputText:String)-> Observable<Any>{
        print("請求網(wǎng)絡(luò)了 \(Thread.current)") // data
        return Observable<Any>.create({ (ob) -> Disposable in
            if inputText == "1234" {
                ob.onError(NSError.init(domain: "com.smart_M.cn", code: 10086, userInfo: nil))
            }// json  - model username pasword
            // username passopp - lgError  - 8001 - httpCoder 100 - 500
            // 封裝 vm - error -
            DispatchQueue.global().async {
                print("發(fā)送之前看看: \(Thread.current)")
                ob.onNext("已經(jīng)輸入:\(inputText)")
                ob.onCompleted()
            }
            return Disposables.create()
        })

運行代碼,并在inputTF輸入內(nèi)容1,打印如下:

請求網(wǎng)絡(luò)了 <NSThread: 0x600000063b40>{number = 1, name = main}
發(fā)送之前看看: <NSThread: 0x604000269600>{number = 4, name = (null)}
請求網(wǎng)絡(luò)了 <NSThread: 0x600000063b40>{number = 1, name = main}
訂閱到了--:已經(jīng)輸入:1
發(fā)送之前看看: <NSThread: 0x604000463c80>{number = 5, name = (null)}
訂閱到了--:已經(jīng)輸入:1---<NSThread: 0x604000463c80>{number = 5, name = (null)}

輸入內(nèi)容1234, 打印error如下:

請求網(wǎng)絡(luò)了 <NSThread: 0x600000063b40>{number = 1, name = main}
Unhandled error happened: Error Domain=com.lgcooci.cn Code=10086 "(null)"
 subscription called from:

發(fā)送之前看看: <NSThread: 0x604000462040>{number = 7, name = (null)}
請求網(wǎng)絡(luò)了 <NSThread: 0x600000063b40>{number = 1, name = main}
Unhandled error happened: Error Domain=com.lgcooci.cn Code=10086 "(null)"
 subscription called from:

發(fā)送之前看看: <NSThread: 0x6000004798c0>{number = 6, name = (null)}

從上面的打印可以看出:

  • 多次訂閱就會多次請求,浪費網(wǎng)絡(luò)
  • 數(shù)據(jù)請求回來以后還在是 子線程
  • 多次執(zhí)行錯誤事件

解決方法:

  1. 開啟網(wǎng)絡(luò)共享
.share(replay: 1, scope: .whileConnected)
  1. 切換到主線程跟新UI
.observeOn(MainScheduler())

3.檢測錯誤事件(不會反悔error,導(dǎo)致崩潰)

.catchErrorJustReturn("檢測到了錯誤事件")
  1. 完整代碼:
let result  = inputTF.rx.text.skip(1)
            .flatMap { [weak self](input) -> Observable<Any> in
                return (self?.dealwithData(inputText:input ?? ""))!
                        .observeOn(MainScheduler())
                        .catchErrorJustReturn("檢測到了錯誤事件")
        }
        .share(replay: 1, scope: .whileConnected)
  1. 執(zhí)行結(jié)果如下:
----------輸入1:
請求網(wǎng)絡(luò)了 <NSThread: 0x604000078d00>{number = 1, name = main}
發(fā)送之前看看: <NSThread: 0x604000473200>{number = 5, name = (null)}
訂閱到了--:已經(jīng)輸入:1
訂閱到了--:已經(jīng)輸入:1---<NSThread: 0x604000078d00>{number = 1, name = main}

----------輸入1234:
請求網(wǎng)絡(luò)了 <NSThread: 0x604000078d00>{number = 1, name = main}
訂閱到了--:檢測到了錯誤事件
訂閱到了--:檢測到了錯誤事件---<NSThread: 0x604000078d00>{number = 1, name = main}
發(fā)送之前看看: <NSThread: 0x60000066d2c0>{number = 6, name = (null)}

上面的問題雖然解決了,但是:

  • 我們修改了很多代碼,那有沒有更好的解決方案呢
  • 這時候就該我們的老司機Driver出場了
Driver 的簡單使用
  • 網(wǎng)絡(luò)共享
  • 綁定到了UI - 主線程
  • 直接處理錯誤,返回 非error(直接顯示在UI)
//observale -> driver
let result  = inputTF.rx.text.orEmpty
            .asDriver()
            .flatMap {
                return self.dealwithData(inputText: $0)
                    .asDriver(onErrorJustReturn: "檢測到了錯誤事件")
            }
// 綁定到了UI - 主線程
// titlt - 非error
 result.map { "長度: \(($0 as! String).count)"}.drive(self.textLabel.rx.text)

 result.map { "\($0 as! String)"}
            .drive(self.btn.rx.title())

執(zhí)行代碼打印如下:

圖片.png
Driver 源碼解析

asDriverControlProperty的擴展方法,返回一個Driver對象

extension ControlProperty {
    public func asDriver() -> Driver<Element> {
        return self.asDriver { _ -> Driver<Element> in
            #if DEBUG
                rxFatalError("Somehow driver received error from a source that shouldn't fail.")
            #else
                return Driver.empty()
            #endif
        }
    }
}

Driver又是SharedSequence的序列別名

public typealias Driver<Element> = SharedSequence<DriverSharingStrategy, Element>
  • 網(wǎng)絡(luò)共享:source.share(replay: 1, scope: .whileConnected)
public struct DriverSharingStrategy: SharingStrategyProtocol {
    public static var scheduler: SchedulerType { return SharingScheduler.make() }
    public static func share<Element>(_ source: Observable<Element>) -> Observable<Element> {
        return source.share(replay: 1, scope: .whileConnected)
    }
}
  • 切換到主線程: 進入上邊SharingScheduler內(nèi)部make()方法
public enum SharingScheduler {
    /// Default scheduler used in SharedSequence based traits.
    public private(set) static var make: () -> SchedulerType = { MainScheduler() }
}
  • 錯誤處理: ObservableConvertibleType的擴展方法public func asDriver(onErrorJustReturn: Element) -> Driver<Element> 中:
  • observeOn(DriverSharingStrategy.scheduler進行線程調(diào)度
  • catchErrorJustReturn(onErrorJustReturn)錯誤處理
extension ObservableConvertibleType {
    ...
    public func asDriver(onErrorJustReturn: Element) -> Driver<Element> {
        let source = self
            .asObservable()
            .observeOn(DriverSharingStrategy.scheduler)
            .catchErrorJustReturn(onErrorJustReturn)
        return Driver(source)
    }
  ...
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • error code(錯誤代碼)=0是操作成功完成。error code(錯誤代碼)=1是功能錯誤。error c...
    Heikki_閱讀 3,531評論 1 9
  • 前言 Driver(老司機?),它是一個精心準(zhǔn)備的特征序列,它主要是為了簡化 UI 層的代碼,也即是提供一種簡便的...
    Henry_Jeannie閱讀 1,666評論 1 4
  • error code(錯誤代碼)=2000是無效的像素格式。error code(錯誤代碼)=2001是指定的驅(qū)動...
    Heikki_閱讀 2,190評論 0 4
  • 前言 這篇文章從實際的代碼上去分析,在RxSwift中為什么要使用Driver以及應(yīng)該如何使用Driver 通過網(wǎng)...
    傷心的EasyMan閱讀 913評論 1 2
  • 一、概述二、Single三、Completable四、Maybe五、Driver六、Signal七、Control...
    yahibo閱讀 870評論 1 6

友情鏈接更多精彩內(nèi)容