美文网首页
07.RxSwift 高阶函数(Driver)

07.RxSwift 高阶函数(Driver)

作者: smart_M | 来源:发表于2019-08-25 16:50 被阅读0次
  1. 首先我们创建一个:序列的中的序列 - string - 映射 - 序列,并且发起多次订阅,如下代码:
//创建序列
let result  = inputTF.rx.text.skip(1)
            .flatMap { [weak self](input) -> Observable<Any> in
                return (self?.dealwithData(inputText:input ?? ""))!
        }

//连续订阅两次
        result.subscribe(onNext: { (element) in
            print("订阅到了--:\(element)")
        })
        result.subscribe(onNext: { (element) in
            print("订阅到了--:\(element)---\(Thread.current)")
        })

//模拟网络请求
func dealwithData(inputText:String)-> Observable<Any>{
        print("请求网络了 \(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("发送之前看看: \(Thread.current)")
                ob.onNext("已经输入:\(inputText)")
                ob.onCompleted()
            }
            return Disposables.create()
        })

运行代码,并在inputTF输入内容1,打印如下:

请求网络了 <NSThread: 0x600000063b40>{number = 1, name = main}
发送之前看看: <NSThread: 0x604000269600>{number = 4, name = (null)}
请求网络了 <NSThread: 0x600000063b40>{number = 1, name = main}
订阅到了--:已经输入:1
发送之前看看: <NSThread: 0x604000463c80>{number = 5, name = (null)}
订阅到了--:已经输入:1---<NSThread: 0x604000463c80>{number = 5, name = (null)}

输入内容1234, 打印error如下:

请求网络了 <NSThread: 0x600000063b40>{number = 1, name = main}
Unhandled error happened: Error Domain=com.lgcooci.cn Code=10086 "(null)"
 subscription called from:

发送之前看看: <NSThread: 0x604000462040>{number = 7, name = (null)}
请求网络了 <NSThread: 0x600000063b40>{number = 1, name = main}
Unhandled error happened: Error Domain=com.lgcooci.cn Code=10086 "(null)"
 subscription called from:

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

从上面的打印可以看出:

  • 多次订阅就会多次请求,浪费网络
  • 数据请求回来以后还在是 子线程
  • 多次执行错误事件

解决方法:

  1. 开启网络共享
.share(replay: 1, scope: .whileConnected)
  1. 切换到主线程跟新UI
.observeOn(MainScheduler())

3.检测错误事件(不会反悔error,导致崩溃)

.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. 执行结果如下:
----------输入1:
请求网络了 <NSThread: 0x604000078d00>{number = 1, name = main}
发送之前看看: <NSThread: 0x604000473200>{number = 5, name = (null)}
订阅到了--:已经输入:1
订阅到了--:已经输入:1---<NSThread: 0x604000078d00>{number = 1, name = main}

----------输入1234:
请求网络了 <NSThread: 0x604000078d00>{number = 1, name = main}
订阅到了--:检测到了错误事件
订阅到了--:检测到了错误事件---<NSThread: 0x604000078d00>{number = 1, name = main}
发送之前看看: <NSThread: 0x60000066d2c0>{number = 6, name = (null)}

上面的问题虽然解决了,但是:

  • 我们修改了很多代码,那有没有更好的解决方案呢
  • 这时候就该我们的老司机Driver出场了
Driver 的简单使用
  • 网络共享
  • 绑定到了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())

执行代码打印如下:

图片.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>
  • 网络共享: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内部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进行线程调度
  • catchErrorJustReturn(onErrorJustReturn)错误处理
extension ObservableConvertibleType {
    ...
    public func asDriver(onErrorJustReturn: Element) -> Driver<Element> {
        let source = self
            .asObservable()
            .observeOn(DriverSharingStrategy.scheduler)
            .catchErrorJustReturn(onErrorJustReturn)
        return Driver(source)
    }
  ...
}

相关文章

  • 07.RxSwift 高阶函数(Driver)

    首先我们创建一个:序列的中的序列 - string - 映射 - 序列,并且发起多次订阅,如下代码: 运行代码,并...

  • RxSwift-Driver探究(三)

    Driver Driver是RxSwift里的一个高阶函数,一般我们会在发送网络请求时,将请求后的数据drive到...

  • RxSwift源码分析(8)——高阶函数核心逻辑

    想要使用RxSwift使用得爽,肯定绕不开高阶函数,比如有map、combineLatest、Driver、pub...

  • RxSwift源码分析(10)——asDriver

    在日常实践开发中,经常会用到一个高阶函数,就是asDriver,而asDriver函数涉及到一个类——Driver...

  • python学习(三)函数式编程

    高阶函数 函数也是变量,函数参数为函数的函数,称作高阶函数 自定义高阶函数 内建高阶函数 map/reducema...

  • 11.Lambda和高阶函数(Lambda and Higher

    高阶函数 kotlin_Lambda,高阶函数 *swift_高阶函数

  • Python | 高阶函数基本应用及Decorator装饰器

    一、高阶函数 理解什么是高阶函数?以及高阶函数的基本应用方法 ▲ 高阶函数 在了解什么是高阶函数之前,我们来看几个...

  • 四、函数进阶

    一. 高阶函数 参数类型包含函数类型或返回值类型为函数类型的函数为高阶函数。 常见的高阶函数 高阶函数的调用 二....

  • Kotlin 高阶函数

    什么是高阶函数 将函数作为参数或者返回值的,称高阶函数。 定义高阶函数 action是一个高阶函数,(Int) -...

  • 高阶组件

    高阶组件 先来引入这个概念 高阶函数是什么? 高阶函数就是一个函数返回一个函数eg: 高阶组件 类同 高阶组件就是...

网友评论

      本文标题:07.RxSwift 高阶函数(Driver)

      本文链接:https://www.haomeiwen.com/subject/gxohectx.html