RxSwift(3)—— Observable序列的创建方式

就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!


RxSwift目录直通车--- 和谐学习,不急不躁!


序列在RxSwift的世界里面是非常重要,平时开发过程用好序列的创建,能够给开发带来事半功倍的效果!这个篇章总结了常用的序列创建方式

1:emty

首先来一个空的序列 - 本来序列事件是Int类型的,这里调用emty函数 没有序列,只能complete

print("********emty********")
let emtyOb = Observable<Int>.empty()
_ = emtyOb.subscribe(onNext: { (number) in
    print("订阅:",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("完成回调")
}) {
    print("释放回调")
}
  • 这种方式不常用,但是我们以点及面展开分析
  • 通过源码解析查看
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
    observer.on(.completed)
    return Disposables.create()
}
  • 很明显在订阅的时候,直接observer.on(.completed) 发送了完成信号,非常简洁

2: just

  • 单个信号序列创建
  • 该方法通过传入一个默认值来初始化,构建一个只有一个元素的Observable队列,订阅完信息自动complete
  • 下面的样例,我们显示地标注出了Observable的类型为Observable<[String]>,即指定了这个 Observable 所发出的事件携带的数据类型必须是String 类型
print("********just********")
//MARK:  just
// 单个信号序列创建
let array = ["LG_Cooci","LG_Kody"]
Observable<[String]>.just(array)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

_ = Observable<[String]>.just(array).subscribe(onNext: { (number) in
    print("订阅:",number)
}, onError: { (error) in
    print("error:",error)
}, onCompleted: {
    print("完成回调")
}) {
    print("释放回调")
}
  • 感觉有点数据便利的感觉
  • 这个序列在平时开发里面还是应用挺多的,看看底层源码
override func subscribe<O: ObserverType>(_ observer: O) -> Disposable where O.E == Element {
    observer.on(.next(self._element))
    observer.on(.completed)
    return Disposables.create()
}
  • observer.on(.next(self._element))常规订阅之后就会发送.next事件
  • 之后就会自动发送完成事件,跟我们效果完全吻合

3:of

  • 此方法创建一个新的可观察实例,该实例具有可变数量的元素。
  • 该方法可以接受可变数量的参数(必需要是同类型的)
print("********of********")
//MARK:  of
// 多个元素 - 针对序列处理
Observable<String>.of("LG_Cooci","LG_Kody")
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 字典
Observable<[String: Any]>.of(["name":"LG_Cooci","age":18])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 数组
Observable<[String]>.of(["LG_Cooci","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
  • 无论字典,数组多个元素都是正常使用
  • 底层源码的结构也是中规中矩
  • 初始化保存调度环境和传入的元素
  • 订阅流程也是利用sink,然后通过mutableIterator迭代器处理发送

4:from

  • 将可选序列转换为可观察序列。
  • 从集合中获取序列:数组,集合,set 获取序列 - 有可选项处理 - 更安全
print("********from********")
// MARK:  from
Observable<[String]>.from(optional: ["LG_Cooci","LG_Kody"])
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)
  • self._optional = optional底层初始化可选项保存
  • 订阅流程判断是否匹配我们的可选项
  • 发送observer.on(.next(element))序列
  • 随即自动observer.on(.completed)完成序列发送

5:deferred

  • 返回一个可观察序列,该序列在新观察者订阅时调用指定的工厂函数。
  • 这里有一个需求:动态序列 - 根据外界的标识 - 动态输出
  • 使用deferred()方法延迟Observable序列的初始化,通过传入的block来实现Observable序列的初始化并且返回。
print("********defer********")
//MARK:  defer
var isOdd = true
_ = Observable<Int>.deferred { () -> Observable<Int> in
    // 这里设计我们的序列
    isOdd = !isOdd
    if isOdd {
        return Observable.of(1,3,5,7,9)
    }
    return Observable.of(0,2,4,6,8)
    }
    .subscribe { (event) in
        print(event)
    }
  • self._observableFactory = observableFactory初始化保存了这段工厂闭包
func run() -> Disposable {
    do {
        let result = try self._observableFactory()
        return result.subscribe(self)
    }
    catch let e {
        self.forwardOn(.error(e))
        self.dispose()
        return Disposables.create()
    }
}
  • 在订阅流程到sink的时候,把这段工厂闭包执行
  • 有种中间层被包装的感觉

6:rang

  • 使用指定的调度程序生成并发送观察者消息,生成指定范围内的可观察整数序列。
print("********rang********")
//MARK:  rang
Observable.range(start: 2, count: 5)
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 底层源码
init(start: E, count: E, scheduler: ImmediateSchedulerType) {
    self._start = start
    self._count = count
    self._scheduler = scheduler
}

override func run<O : ObserverType>(_ observer: O, cancel: Cancelable) -> (sink: Disposable, subscription: Disposable) where O.E == E {
    let sink = RangeSink(parent: self, observer: observer, cancel: cancel)
    let subscription = sink.run()
    return (sink: sink, subscription: subscription)
}
  • 保存序列中第一个整数的值。
  • 保存要生成的顺序整数的数目。
  • 保存调度环境
if i < self._parent._count {
    self.forwardOn(.next(self._parent._start + i))
    recurse(i + 1)
}
else {
    self.forwardOn(.completed)
    self.dispose()
}
  • 根据之前保存的信息,数据的状态也不断攀升,然后递归到规定的要求

7:generate

  • 通过运行产生序列元素的状态驱动循环,使用指定的调度程序运行循环,发送观察者消息,从而生成一个可观察序列。
  • 该方法创建一个只有当提供的所有的判断条件都为 true 的时候,才会给出动作的 Observable 序列。
  • 初始值给定 然后判断条件1判断条件2 会一直递归下去,直到条件1或者条件2不满足
  • 类似 数组遍历循环
  • -参数一initialState: 初始状态。
  • -参数二 condition:终止生成的条件(返回“false”时)。
  • -参数三 iterate:迭代步骤函数。
  • -参数四 调度器:用来运行生成器循环的调度器,默认:CurrentThreadScheduler.instance
  • -返回:生成的序列。
print("********generate********")
//MARK:  generate
Observable.generate(initialState: 0,// 初始值
                    condition: { $0 < 10}, // 条件1
                    iterate: { $0 + 2 })  // 条件2 +2
    .subscribe { (event) in
        print(event)
    }.disposed(by: disposeBag)

// 数组遍历
let arr = ["LG_Cooci_1","LG_Cooci_2","LG_Cooci_3","LG_Cooci_4","LG_Cooci_5","LG_Cooci_6","LG_Cooci_7","LG_Cooci_8","LG_Cooci_9","LG_Cooci_10"]
Observable.generate(initialState: 0,// 初始值
    condition: { $0 < arr.count}, // 条件1
    iterate: { $0 + 1 })  // 条件2 +2
    .subscribe(onNext: {
        print("遍历arr:",arr[$0])
    })
    .disposed(by: disposeBag)

8:timer

  • 返回一个可观察序列,该序列使用指定的调度程序运行计时器,在指定的初始相对到期时间过后定期生成一个值。
  • 第一次参数:第一次响应距离现在的时间
  • 第二个参数:时间间隔
  • 第三个参数:线程
print("********timer********")
//MARK:  timer
Observable<Int>.timer(5, period: 2, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
.disposed(by: disposeBag)

// 因为没有指定期限period,故认定为一次性
Observable<Int>.timer(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print("111111111 \(event)")
    }
    //.disposed(by: disposeBag)
  • 状态码的不断攀升,间隔时间不断发送响应

9:interval

  • 返回一个可观察序列,该序列在每个周期之后生成一个值,使用指定的调度程序运行计时器并发送观察者消息。
print("********interval********")
//MARK:  interval
// 定时器
Observable<Int>.interval(1, scheduler: MainScheduler.instance)
    .subscribe { (event) in
        print(event)
    }
    //.disposed(by: disposeBag)

9:repeatElement

  • 使用指定的调度程序发送观察者消息,生成无限重复给定元素的可观察序列。
print("********repeatElement********")
//MARK:  repeatElement
Observable<Int>.repeatElement(5)
    .subscribe { (event) in
        // print("订阅:",event)
    }
    .disposed(by: disposeBag)

10:error

  • 返回一个以“error”结束的可观察序列。
  • 这个序列平时在开发也比较常见,请求网络失败也会发送失败信号!
print("********error********")
//MARK:  error
// 对消费者发出一个错误信号
Observable<String>.error(NSError.init(domain: "lgerror", code: 10086, userInfo: ["reason":"unknow"]))
    .subscribe { (event) in
        print("订阅:",event)
    }
    .disposed(by: disposeBag)

11:never

  • 该方法创建一个永远不会发出 Event(也不会终止)的 Observable 序列。
  • 这种类型的响应源 在测试或者在组合操作符中禁用确切的源非常有用
print("********never********")
//MARK:  never
Observable<String>.never()
    .subscribe { (event) in
        print("走你",event)
    }
    .disposed(by: disposeBag)
print("********never********") 

12:create()

  • 该方法接受一个 闭包形式的参数,任务是对每一个过来的订阅进行处理。
  • 下面是一个简单的样例。为方便演示,这里增加了订阅相关代码
  • 这也是序列创建的一般方式,应用非常之多
let observable = Observable<String>.create{observer in
    //对订阅者发出了.next事件,且携带了一个数据"hangge.com"
    observer.onNext("hangge.com")
    //对订阅者发出了.completed事件
    observer.onCompleted()
    //因为一个订阅行为会有一个Disposable类型的返回值,所以在结尾一定要returen一个Disposable
    return Disposables.create()
}
 
//订阅测试
observable.subscribe {
    print($0)
}

序列的创建也是学习 RxSwift 的根基,有很多时候我遇到很多的BUG,说白了就是根基没有掌握好!现在我们的已经RxSwift第十节课上完了,很多同学对RxSwift有了一个比较深入的了解,当然这里我还是以博客的形式写出来,就是希望大家能够及时回来看看,我知道,肯定会有很多同学回来继续加深基础的!

就问此时此刻还有谁?45度仰望天空,该死!我这无处安放的魅力!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容