| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
njhu5107
8年前发布

RxSwift入坑解读-你所需要知道的各种概念

   <p>相信大家很早就听说过函数式响应编程概念,我是去年面试的时候接触到函数式响应编程的,当时也是第一次接触到MVVM这个概念,转眼都一年过去了,我却没有在函数式编程上做深入的研究,说来还真是惭愧。</p>    <p>不过最近由于想要使用RxSwift,所以趁这个时候好好接触和研究一下传说中的函数式编程,由于网上关于RxSwift的教程资料很少,这篇文章其实就是最RxSwift官方文档和一些概念做一些解读。算是大家学习的参考文章吧! 先挖个坑,这可能会是一个RxSwift系列,希望大家在学习的时候有所参考。</p>    <h2>RxSwift是什么</h2>    <p>RxSwif是 ReactiveX 的Swift版本,也就是一个函数式响应编程的框架。对,就这一句话。想要知道他做什么的,我们先来了解一下观察者模式。</p>    <h2>观察者模式</h2>    <p>关于观察者模式我想大伙应该都很了解了吧,什么KVO,通知等都是观察者模式,在设计模式中他可是一个重中之重的设计模式啊!比如一个宝宝在睡觉,爸爸妈妈,爷爷奶奶总不能在那边一只看着吧?那样子太累了。他们该做啥事就做啥事呗,只要听到宝宝的哭声,他们就给宝宝喂奶就行了。这就是一个典型的观察者模式。宝宝是被观察者,爸爸妈妈等是观察者也称作订阅者,只要被观察者发出了某些事件比如宝宝哭声、叫声都是一个事件,通知到订阅者,订阅者们就可以做相应的处理工作。哈哈,观察者模式很简单吧?</p>    <h2>RxSwift做了什么</h2>    <p>RxSwift把我们程序中每一个操作都看成一个事件,比如一个TextField中的文本改变,一个按钮被点击,或者一个网络请求结束等,每一个事件源就可以看成一个管道,也就是sequence,比如TextField,当我们改变里面的文本的时候,这个TextField就会不断的发出事件,从他的这个sequence中不断的流出,我们只需要监听这个sequence,每流出一个事件就做相应的处理。同理,Button也是一个sequence,每点击一次就流出一个事件。也就是我们把每一步都想成是一个事件就好去理解RxSwift了。看下图是不是很好理解了?</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/258aaed7921e7a56670957733cbd48e0.jpg"></p>    <p>sequence.png</p>    <h2>Observable和Observer</h2>    <p>理解了观察者模式这两个概念就很好理解了,Observable就是可被观察的,也就是我们说的宝宝,他也是事件源。而Observer就是我们的观察者,也就是当收到事件的时候去做某些处理的爸爸妈妈。观察者需要去订阅(subscribe)被观察者,才能收到Observable的事件通知消息。</p>    <p>下面开始一些基本概念解读,通读一遍你会对RxSwift有非常深刻的认识了,其实也就是对整理了一下官方文档和加上自己的一些理解</p>    <h2>创建和订阅被观察者</h2>    <p>下面创建被观察者其实就是创建一个Obserable的sequence,就是创建一个流,然后就可以被订阅subscribe,这样被观察者发出时间消失,我们就能做相应的处理</p>    <h3>DisposeBag</h3>    <p>DisposeBag其实就相当于iOS中的ARC似得,会在适当的时候销毁观察者,相当于内存管理者吧。</p>    <h3>subscribe</h3>    <p>subscribe是订阅sequence发出的事件,比如next事件,error事件等。而subscribe(onNext:)是监听sequence发出的next事件中的element进行处理,他会忽略error和completed事件。相对应的还有subscribe(onError:) 和 subscribe(onCompleted:)</p>    <h3>never</h3>    <p>never就是创建一个sequence,但是不发出任何事件信号。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/a2c9591c2c91614a0c26704afbce6f41.jpg"></p>    <p>never.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  let neverSequence = Observable<String>.never()    let neverSequenceSubscription = neverSequence      .subscribe { _ in          print("This will never be printed")  }.addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">结果是什么都不打印</code></pre>    <h3>empty</h3>    <p>empty就是创建一个空的sequence,只能发出一个completed事件</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/c02585d921bb7c029aaa979419ef438b.jpg"></p>    <p>empty.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()        Observable<Int>.empty()          .subscribe { event in              print(event)          }          .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">completed</code></pre>    <h3>just</h3>    <p>just是创建一个sequence只能发出一种特定的事件,能正常结束</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/8476874f0a288e947d2f08158dd6faca.jpg"></p>    <p>just.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.just(":red_circle:")      .subscribe { event in          print(event)      }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">next(:red_circle:)  completed</code></pre>    <h3>of</h3>    <p>of是创建一个sequence能发出很多种事件信号</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":dog:", ":cat:", ":mouse:", ":hamster:")      .subscribe(onNext: { element in          print(element)      })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:dog:  :cat:  :mouse:  :hamster:</code></pre>    <p>如果把上面的onNext:去掉的话,结果会是这样子,也正好对应了我们subscribe中,subscribe只监听事件。</p>    <pre>  <code class="language-swift">next(:dog:)  next(:cat:)  next(:mouse:)  next(:hamster:)  completed</code></pre>    <h3>from</h3>    <p>from就是从集合中创建sequence,例如数组,字典或者Set</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.from([":dog:", ":cat:", ":mouse:", ":hamster:"])      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>create</h3>    <p>我们也可以自定义可观察的sequence,那就是使用create</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/710977506ff157aff223427240d9337a.jpg"></p>    <p>create.png</p>    <p>create操作符传入一个观察者observer,然后调用observer的onNext,onCompleted和onError方法。返回一个可观察的obserable序列。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let myJust = { (element: String) -> Observable<String> in      return Observable.create { observer in          observer.on(.next(element))          observer.on(.completed)          return Disposables.create()      }  }    myJust(":red_circle:")      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">next(:red_circle:)  completed</code></pre>    <h3>range</h3>    <p>range就是创建一个sequence,他会发出这个范围中的从开始到结束的所有事件</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/3cc9a076125952c800b7df48b9a96a80.jpg"></p>    <p>range.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.range(start: 1, count: 10)      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">next(1)  next(2)  next(3)  next(4)  next(5)  next(6)  next(7)  next(8)  next(9)  next(10)  completed</code></pre>    <h3>repeatElement</h3>    <p>创建一个sequence,发出特定的事件n次</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/fb97ba8c28f199f80a47e11e79dfe049.jpg"></p>    <p>repeat.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.repeatElement(":red_circle:")      .take(3)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:red_circle:  :red_circle:  :red_circle:</code></pre>    <h3>generate</h3>    <p>generate是创建一个可观察sequence,当初始化的条件为true的时候,他就会发出所对应的事件</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.generate(          initialState: 0,          condition: { $0 < 3 },          iterate: { $0 + 1 }      )      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>deferred</h3>    <p>deferred会为每一为订阅者observer创建一个新的可观察序列</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/ebca18ee3b866e80a4f56dfea99d431f.jpg"></p>    <p>defered.png</p>    <p>下面例子中每次进行subscribe的时候都会去创建一个新的deferredSequence,所以Emitting会打印两遍。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  var count = 1    let deferredSequence = Observable<String>.deferred {      print("Creating \(count)")      count += 1        return Observable.create { observer in          print("Emitting...")          observer.onNext(":dog:")          observer.onNext(":cat:")          observer.onNext(":monkey_face:")          return Disposables.create()      }  }    deferredSequence      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    deferredSequence      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">Creating 1  Emitting...  :dog:  :cat:  :monkey_face:  Creating 2  Emitting...  :dog:  :cat:  :monkey_face:</code></pre>    <h3>error</h3>    <p>创建一个可观察序列,但不发出任何正常的事件,只发出error事件并结束</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable<Int>.error(TestError.test)      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">error(test)</code></pre>    <h3>doOn</h3>    <p>doOn我感觉就是在直接onNext处理时候,先执行某个方法,doOnNext( <em>:)方法就是在subscribe(onNext:)前调用,doOnCompleted(</em> :)就是在subscribe(onCompleted:)前面调用的。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":apple:", ":pear:", ":tangerine:", ":lemon:")      .do(onNext: { print("Intercepted:", $0) }, onError: { print("Intercepted error:", $0) }, onCompleted: { print("Completed")  })      .subscribe(onNext: { print($0) },onCompleted: { print("结束") })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">Intercepted: :apple:  :apple:  Intercepted: :pear:  :pear:  Intercepted: :tangerine:  :tangerine:  Intercepted: :lemon:  :lemon:  Completed  结束</code></pre>    <h2>学会使用Subjects</h2>    <p>Subjet是observable和Observer之间的桥梁,一个Subject既是一个Obserable也是一个Observer,他既可以发出事件,也可以监听事件。</p>    <h3>PublishSubject</h3>    <p>当你订阅PublishSubject的时候,你只能接收到订阅他之后发生的事件。subject.onNext()发出onNext事件,对应的还有onError()和onCompleted()事件</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/a9fa3aac990705c7c1d9344fa7086135.jpg"></p>    <p>publishsubject.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  let subject = PublishSubject<String>()    subject.addObserver("1").addDisposableTo(disposeBag)  subject.onNext(":dog:")  subject.onNext(":cat:")    subject.addObserver("2").addDisposableTo(disposeBag)  subject.onNext(":a:")  subject.onNext(":b:")</code></pre>    <pre>  <code class="language-swift">Subscription: 1 Event: next(:dog:)  Subscription: 1 Event: next(:cat:)  Subscription: 1 Event: next(:a:)  Subscription: 2 Event: next(:a:)  Subscription: 1 Event: next(:b:)  Subscription: 2 Event: next(:b:)</code></pre>    <h3>ReplaySubject</h3>    <p>当你订阅ReplaySubject的时候,你可以接收到订阅他之后的事件,但也可以接受订阅他之前发出的事件,接受几个事件取决与bufferSize的大小</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/52a2be702a80510b6c9d0cce6e1b72d4.jpg"></p>    <p>replaysubject.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  let subject = ReplaySubject<String>.create(bufferSize: 1)    subject.addObserver("1").addDisposableTo(disposeBag)  subject.onNext(":dog:")  subject.onNext(":cat:")    subject.addObserver("2").addDisposableTo(disposeBag)  subject.onNext(":a:")  subject.onNext(":b:")</code></pre>    <pre>  <code class="language-swift">Subscription: 1 Event: next(:dog:)  Subscription: 1 Event: next(:cat:)  Subscription: 2 Event: next(:cat:) //订阅之后还可以接受一次前面发出的事件  Subscription: 1 Event: next(:a:)  Subscription: 2 Event: next(:a:)  Subscription: 1 Event: next(:b:)  Subscription: 2 Event: next(:b:)</code></pre>    <h3>BehaviorSubject</h3>    <p>当你订阅了BehaviorSubject,你会接受到订阅之前的最后一个事件。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/1722e606b0df8b5bc6b3ad534b89a2f0.jpg"></p>    <p>behaviorsubject.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  let subject = BehaviorSubject(value: ":red_circle:")    subject.addObserver("1").addDisposableTo(disposeBag)  subject.onNext(":dog:")  subject.onNext(":cat:")    subject.addObserver("2").addDisposableTo(disposeBag)  subject.onNext(":a:")  subject.onNext(":b:")    subject.addObserver("3").addDisposableTo(disposeBag)  subject.onNext(":pear:")  subject.onNext(":tangerine:")</code></pre>    <pre>  <code class="language-swift">Subscription: 1 Event: next(:red_circle:)  Subscription: 1 Event: next(:dog:)  Subscription: 1 Event: next(:cat:)  Subscription: 2 Event: next(:cat:)    //订阅之前的最后一个事件  Subscription: 1 Event: next(:a:)  Subscription: 2 Event: next(:a:)  Subscription: 1 Event: next(:b:)  Subscription: 2 Event: next(:b:)  Subscription: 3 Event: next(:b:) //订阅之前的最后一个事件  Subscription: 1 Event: next(:pear:)  Subscription: 3 Event: next(:pear:)  Subscription: 2 Event: next(:pear:)  Subscription: 1 Event: next(:tangerine:)  Subscription: 3 Event: next(:tangerine:)  Subscription: 2 Event: next(:tangerine:)</code></pre>    <p>PublishSubject, ReplaySubject和BehaviorSubject是不会自动发出completed事件的。</p>    <h3>Variable</h3>    <p>Variable是BehaviorSubject一个包装箱,就像是一个箱子一样,使用的时候需要调用asObservable()拆箱,里面的value是一个BehaviorSubject,他不会发出error事件,但是会自动发出completed事件。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  let variable = Variable(":red_circle:")    variable.asObservable().addObserver("1").addDisposableTo(disposeBag)  variable.value = ":dog:"  variable.value = ":cat:"    variable.asObservable().addObserver("2").addDisposableTo(disposeBag)  variable.value = ":a:"  variable.value = ":b:"</code></pre>    <pre>  <code class="language-swift">Subscription: 1 Event: next(:red_circle:)  Subscription: 1 Event: next(:dog:)  Subscription: 1 Event: next(:cat:)  Subscription: 2 Event: next(:cat:)  Subscription: 1 Event: next(:a:)  Subscription: 2 Event: next(:a:)  Subscription: 1 Event: next(:b:)  Subscription: 2 Event: next(:b:)  Subscription: 1 Event: completed  Subscription: 2 Event: completed</code></pre>    <h2>联合操作</h2>    <p>联合操作就是把多个Observable流合成单个Observable流</p>    <h3>startWith</h3>    <p>在发出事件消息之前,先发出某个特定的事件消息。比如发出事件2 ,3然后我startWith(1),那么就会先发出1,然后2 ,3.</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/54332de646ea7cf6f0d653c55b215f08.jpg"></p>    <p>startwith.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of("2", "3")      .startWith("1")      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>merge</h3>    <p>合并两个Observable流合成单个Observable流,根据时间轴发出对应的事件</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/3dc93adebee7e1eaa8d634d324fe2e23.jpg"></p>    <p>merge.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let subject1 = PublishSubject<String>()  let subject2 = PublishSubject<String>()    Observable.of(subject1, subject2)      .merge()      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    subject1.onNext(":a:")    subject1.onNext(":b:")    subject2.onNext("①")    subject2.onNext("②")    subject1.onNext(":ab:")    subject2.onNext("③")</code></pre>    <pre>  <code class="language-swift">:a:  :b:  ①  ②  :ab:  ③</code></pre>    <h3>zip</h3>    <p>绑定超过最多不超过8个的Observable流,结合在一起处理。注意Zip是一个事件对应另一个流一个事件。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/e1e7381002ed2b8f0b6ee6a9ee97f5c3.jpg"></p>    <p>zip.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let stringSubject = PublishSubject<String>()  let intSubject = PublishSubject<Int>()    Observable.zip(stringSubject, intSubject) { stringElement, intElement in      "\(stringElement) \(intElement)"      }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    stringSubject.onNext(":a:")  stringSubject.onNext(":b:")    intSubject.onNext(1)    intSubject.onNext(2)    stringSubject.onNext(":ab:")  intSubject.onNext(3)</code></pre>    <pre>  <code class="language-swift">:a: 1    将stringSubject和intSubject压缩到一起共同处理  :b: 2  :ab: 3</code></pre>    <h3>combineLatest</h3>    <p>绑定超过最多不超过8个的Observable流,结合在一起处理。和Zip不同的是combineLatest是一个流的事件对应另一个流的最新的事件,两个事件都会是最新的事件,可将下图与Zip的图进行对比。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/e7572078c27af54f52362fb625835d96.jpg"></p>    <p>combinlatest.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let stringSubject = PublishSubject<String>()  let intSubject = PublishSubject<Int>()    Observable.combineLatest(stringSubject, intSubject) { stringElement, intElement in          "\(stringElement) \(intElement)"      }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    stringSubject.onNext(":a:")    stringSubject.onNext(":b:")  intSubject.onNext(1)    intSubject.onNext(2)    stringSubject.onNext(":ab:")</code></pre>    <pre>  <code class="language-swift">:b: 1  :b: 2  :ab: 2</code></pre>    <h3>switchLatest</h3>    <p>switchLatest可以对事件流进行转换,本来监听的subject1,我可以通过更改variable里面的value更换事件源。变成监听subject2了</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/aa64c5f1f3720eb402f45ee8aa6cffb4.jpg"></p>    <p>switch.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let subject1 = BehaviorSubject(value: ":soccer:️")  let subject2 = BehaviorSubject(value: ":apple:")    let variable = Variable(subject1)    variable.asObservable()      .switchLatest()      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    subject1.onNext(":football:")  subject1.onNext(":basketball:")    variable.value = subject2    subject1.onNext(":baseball:")    subject2.onNext(":pear:")  variable.value = subject1  subject2.onNext("田腾飞")  subject1.onNext("沸腾天")</code></pre>    <pre>  <code class="language-swift">:soccer:️  :football:  :basketball:  :apple:  :pear:  :baseball:  沸腾天</code></pre>    <h2>变换操作</h2>    <h3>map</h3>    <p>通过传入一个函数闭包把原来的sequence转变为一个新的sequence的操作</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/0a18fa2143cb0c241046fc22d07d329a.jpg"></p>    <p>transform.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  Observable.of(1, 2, 3)      .map { $0 * $0 }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">1    每一个元素自己相乘  4  9</code></pre>    <h3>flatMap</h3>    <p>将一个sequence转换为一个sequences,当你接收一个sequence的事件,你还想接收其他sequence发出的事件的话可以使用flatMap,她会将每一个sequence事件进行处理以后,然后再以一个sequence形式发出事件。而且flatMap有一次拆包动作,请看代码解析。</p>    <p style="text-align: center;"><img src="https://simg.open-open.com/show/c3f0ad71dcdc8698980473cbf60e49f6.jpg"></p>    <p>flatmap.png</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    struct Player {      var score: Variable<Int>        //里面是一个Variable  }    let :boy|type_1_2: = Player(score: Variable(80))          let :girl|type_3: = Player(score: Variable(90))  let :joy: = Player(score: Variable(550))    let player = Variable(:boy|type_1_2:)  //将player转为Variable    player.asObservable()        //拆箱转成可被监听的sequence      .flatMap { $0.score.asObservable() } // flatMap有一次拆包动作,$0本来应该是一个BehaviorSubject类型,但是直接访问了score。所以猜想flatMap对behaviorSubject进行了onNext拆包取数据      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    :boy|type_1_2:.score.value = 85    player.value = :girl|type_3: //更换了value,相当于又添加了一个sequence,两个sequence都可以接收    :boy|type_1_2:.score.value = 95  :boy|type_1_2:.score.value = 222  player.value = :joy:    :girl|type_3:.score.value = 100</code></pre>    <h3>flatMapLatest</h3>    <p>flatMapLatest只会接收最新的value事件,将上例改为flatMapLatest。结果为</p>    <h3>scan</h3>    <p>scan就是给一个初始化的数,然后不断的拿前一个结果和最新的值进行处理操作。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(10, 100, 1000)      .scan(1) { aggregateValue, newValue in          aggregateValue + newValue      }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h2>过滤和约束</h2>    <h3>filter</h3>    <p>filter很好理解,就是过滤掉某些不符合要求的事件</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(      ":cat:", ":rabbit:", ":dog:",      ":frog:", ":cat:", ":rabbit:",      ":hamster:", ":frog:", ":cat:")      .filter {          $0 == ":cat:"      }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:cat:  :cat:  :cat:</code></pre>    <h3>distinctUntilChanged</h3>    <p>distinctUntilChanged就是当下一个事件与前一个事件是不同事件的事件才进行处理操作</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":pig:", ":cat:", ":cat:", ":cat:", ":monkey_face:", ":cat:")      .distinctUntilChanged()      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:cat:  :pig:  :cat:  :monkey_face:  :cat:</code></pre>    <h3>elementAt</h3>    <p>只处理在指定位置的事件</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .elementAt(3)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:frog:</code></pre>    <h3>single</h3>    <p>找出在sequence只发出一次的事件,如果超过一个就会发出error错误</p>    <pre>  <code class="language-swift">Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .single()      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:cat:    //单一信号超过了一个  Received unhandled error: /var/folders/hz/v15ld5mj0nqf83d21j13y0tw0000gn/T/./lldb/7229/playground107.swift:69:__lldb_expr_107 -> Sequence contains more than one element.</code></pre>    <pre>  <code class="language-swift">Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .single { $0 == ":frog:" }        //青蛙只有一个,completed      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">Observable.of(":cat:", ":rabbit:", ":dog:", ":cat:", ":rabbit:", ":dog:")      .single { $0 == ":rabbit:" } //兔子有两个,会发出error      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .single { $0 == ":large_blue_circle:" } //没有蓝色球,会发出error      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <h3>take</h3>    <p>只处理前几个事件信号,</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .take(3)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:cat:  :rabbit:  :dog:</code></pre>    <h3>takeLast</h3>    <p>只处理后几个事件信号</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .takeLast(3)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:frog:  :pig:  :monkey_face:</code></pre>    <h3>takeWhile</h3>    <p>当条件满足的时候进行处理</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(1, 2, 3, 4, 5, 6)      .takeWhile { $0 < 4 }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>takeUntil</h3>    <p>接收事件消息,直到另一个sequence发出事件消息的时候。</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let sourceSequence = PublishSubject<String>()  let referenceSequence = PublishSubject<String>()    sourceSequence      .takeUntil(referenceSequence)      .subscribe { print($0) }      .addDisposableTo(disposeBag)    sourceSequence.onNext(":cat:")  sourceSequence.onNext(":rabbit:")  sourceSequence.onNext(":dog:")    referenceSequence.onNext(":red_circle:")    //停止接收消息    sourceSequence.onNext(":frog:")  sourceSequence.onNext(":pig:")  sourceSequence.onNext(":monkey_face:")</code></pre>    <pre>  <code class="language-swift">next(:cat:)  next(:rabbit:)  next(:dog:)  completed</code></pre>    <h3>skip</h3>    <p>取消前几个事件</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .skip(2)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">:dog:  :frog:  :pig:  :monkey_face:</code></pre>    <h3>skipWhile</h3>    <p>满足条件的事件消息都取消</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(1, 2, 3, 4, 5, 6)      .skipWhile { $0 < 4 }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>skipWhileWithIndex</h3>    <p>满足条件的都被取消,传入的闭包同skipWhile有点区别而已</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(":cat:", ":rabbit:", ":dog:", ":frog:", ":pig:", ":monkey_face:")      .skipWhileWithIndex { element, index in          index < 3      }      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>skipUntil</h3>    <p>直到某个sequence发出了事件消息,才开始接收当前sequence发出的事件消息</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let sourceSequence = PublishSubject<String>()  let referenceSequence = PublishSubject<String>()    sourceSequence      .skipUntil(referenceSequence)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)    sourceSequence.onNext(":cat:")  sourceSequence.onNext(":rabbit:")  sourceSequence.onNext(":dog:")    referenceSequence.onNext(":red_circle:")    sourceSequence.onNext(":frog:")  sourceSequence.onNext(":pig:")  sourceSequence.onNext(":monkey_face:")  }</code></pre>    <h2>数学操作</h2>    <h3>toArray</h3>    <p>将sequence转换成一个array,并转换成单一事件信号,然后结束</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.range(start: 1, count: 10)      .toArray()      .subscribe { print($0) }      .addDisposableTo(disposeBag)</code></pre>    <pre>  <code class="language-swift">next([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])  completed</code></pre>    <h3>reduce</h3>    <p>用一个初始值,对事件数据进行累计操作。reduce接受一个初始值,和一个操作符号</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    Observable.of(10, 100, 1000)      .reduce(1, accumulator: +)      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>concat</h3>    <p>concat会把多个sequence和并为一个sequence,并且当前面一个sequence发出了completed事件,才会开始下一个sequence的事件。</p>    <p>在第一sequence完成之前,第二个sequence发出的事件都会被忽略,但会接收一完成之前的二发出的最后一个事件。不好解释,看例子说明</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let subject1 = BehaviorSubject(value: ":apple:")  let subject2 = BehaviorSubject(value: ":dog:")    let variable = Variable(subject1)    variable.asObservable()      .concat()      .subscribe { print($0) }      .addDisposableTo(disposeBag)    subject1.onNext(":pear:")  subject1.onNext(":tangerine:")    variable.value = subject2      subject2.onNext(":cat:")    //1完成前,会被忽略  subject2.onNext("teng") //1完成前,会被忽略  subject2.onNext("fei")    //1完成前的最后一个,会被接收    subject1.onCompleted()    subject2.onNext(":mouse:")</code></pre>    <pre>  <code class="language-swift">next(:apple:)  next(:pear:)  next(:tangerine:)  next(fei)  next(:mouse:)</code></pre>    <h2>连接性操作</h2>    <p>Connectable Observable有订阅时不开始发射事件消息,而是仅当调用它们的connect()方法时。这样就可以等待所有我们想要的订阅者都已经订阅了以后,再开始发出事件消息,这样能保证我们想要的所有订阅者都能接收到事件消息。其实也就是等大家都就位以后,开始发出消息。</p>    <h3>publish</h3>    <p>将一个正常的sequence转换成一个connectable sequence</p>    <pre>  <code class="language-swift">let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)      .publish()    _ = intSequence      .subscribe(onNext: { print("Subscription 1:, Event: \($0)") })    delay(2) { _ = intSequence.connect() } //相当于把事件消息推迟了两秒    delay(4) {      _ = intSequence          .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })  }    delay(6) {      _ = intSequence          .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })  }</code></pre>    <pre>  <code class="language-swift">Subscription 1:, Event: 0  Subscription 1:, Event: 1  Subscription 2:, Event: 1  Subscription 1:, Event: 2  Subscription 2:, Event: 2  Subscription 1:, Event: 3  Subscription 3:, Event: 3  Subscription 2:, Event: 3  Subscription 1:, Event: 4  Subscription 3:, Event: 4</code></pre>    <h3>replay</h3>    <p>将一个正常的sequence转换成一个connectable sequence,然后和replaySubject相似,能接收到订阅之前的事件消息。</p>    <pre>  <code class="language-swift">let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)      .replay(5)    //接收到订阅之前的5条事件消息    _ = intSequence      .subscribe(onNext: { print("Subscription 1:, Event: \($0)") })    delay(2) { _ = intSequence.connect() }    delay(4) {      _ = intSequence          .subscribe(onNext: { print("Subscription 2:, Event: \($0)") })  }    delay(8) {      _ = intSequence          .subscribe(onNext: { print("Subscription 3:, Event: \($0)") })  }</code></pre>    <h3>multicast</h3>    <p>将一个正常的sequence转换成一个connectable sequence,并且通过特性的subject发送出去,比如PublishSubject,或者replaySubject,behaviorSubject等。不同的Subject会有不同的结果。</p>    <pre>  <code class="language-swift">let subject = PublishSubject<Int>()    _ = subject      .subscribe(onNext: { print("Subject: \($0)") })    let intSequence = Observable<Int>.interval(1, scheduler: MainScheduler.instance)      .multicast(subject)    _ = intSequence      .subscribe(onNext: { print("\tSubscription 1:, Event: \($0)") })    delay(2) { _ = intSequence.connect() }    delay(4) {      _ = intSequence          .subscribe(onNext: { print("\tSubscription 2:, Event: \($0)") })  }</code></pre>    <h2>错误处理</h2>    <h3>catchErrorJustReturn</h3>    <p>遇到error事件的时候,就return一个值,然后结束</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let sequenceThatFails = PublishSubject<String>()    sequenceThatFails      .catchErrorJustReturn(":blush:")      .subscribe { print($0) }      .addDisposableTo(disposeBag)    sequenceThatFails.onNext(":grimacing:")  sequenceThatFails.onNext(":fearful:")  sequenceThatFails.onNext(":rage:")  sequenceThatFails.onNext(":red_circle:")  sequenceThatFails.onError(TestError.test)</code></pre>    <pre>  <code class="language-swift">next(:grimacing:)  next(:fearful:)  next(:rage:)  next(:red_circle:)  next(:blush:)  completed</code></pre>    <h3>catchError</h3>    <p>捕获error进行处理,可以返回另一个sequence进行订阅</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()    let sequenceThatFails = PublishSubject<String>()  let recoverySequence = PublishSubject<String>()    sequenceThatFails      .catchError {          print("Error:", $0)          return recoverySequence      }      .subscribe { print($0) }      .addDisposableTo(disposeBag)    sequenceThatFails.onNext(":grimacing:")  sequenceThatFails.onNext(":fearful:")  sequenceThatFails.onNext(":rage:")  sequenceThatFails.onNext(":red_circle:")  sequenceThatFails.onError(TestError.test)    recoverySequence.onNext(":blush:")</code></pre>    <pre>  <code class="language-swift">next(:grimacing:)  next(:fearful:)  next(:rage:)  next(:red_circle:)  Error: test  next(:blush:)</code></pre>    <h3>retry</h3>    <p>遇见error事件可以进行重试,比如网络请求失败,可以进行重新连接</p>    <pre>  <code class="language-swift">let disposeBag = DisposeBag()  var count = 1    let sequenceThatErrors = Observable<String>.create { observer in      observer.onNext(":apple:")      observer.onNext(":pear:")      observer.onNext(":tangerine:")        if count == 1 {          observer.onError(TestError.test)          print("Error encountered")          count += 1      }        observer.onNext(":dog:")      observer.onNext(":cat:")      observer.onNext(":mouse:")      observer.onCompleted()        return Disposables.create()  }    sequenceThatErrors      .retry(3)        //不传入数字的话,只会重试一次      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h2>debug</h2>    <h3>debug</h3>    <p>打印所有的订阅, 事件和disposals</p>    <pre>  <code class="language-swift">sequenceThatErrors      .retry(3)      .debug()      .subscribe(onNext: { print($0) })      .addDisposableTo(disposeBag)</code></pre>    <h3>RxSwift.Resources.total</h3>    <p>查看RxSwift所有资源的占用</p>    <pre>  <code class="language-swift">print(RxSwift.Resources.total)</code></pre>    <p>啊,文章终于结束,这篇文章比较长,基本上涵盖了官方文档所有的概念,其中不免有些错误与疏漏,希望能在你学习RxSwift的时候能有一些参考价值吧!!!</p>    <p> </p>    <p> </p>    <p>来自:http://www.jianshu.com/p/a1e2665f9a6c</p>    <p> </p>    
 本文由用户 njhu5107 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1481854306379.html
RxSwift PEAR