接上一篇:初识RxSwift及使用教程 韩俊强的博客

本文档内容来自于 RxSwift 的 Playground。记录大多数 ReactiveX 的概念和操作符。

(部分翻译和注解来自 ReactiveX文档中文翻译)

Introduction

为什么使用 RxSwift?

我们写的很多代码实际上是为了解决和响应外部事件。当用户操作一个控件的时候,我们需要使用 @IBAction 来响应事件。我们需要观察通知来检测键盘改变位置。当 URL Sessions 带着响应的数据返回时,我们需要提供闭包来执行我们的操作。我们还需要使用 KVO 来检测变量的值改变。这些大量的编写机制使得我们的代码结构变的更加复杂。如果有一种统一的编写机制来完成所有的这些调用/响应代码是不是更棒呢?Rx 就是为解决这些问题而生的。

Observable

理解 RxSwift 的关键是理解 Observable 的概念。要理解它的创建,操作以及为了对变化做出响应操作而进行的订阅(subscribe)。

创建和订阅 Observable

要理解本框架,第一步需要理解如何创建 Observable。有很多函数可以创建 Observable。

创建 Observable 之后,如果没有订阅者订阅该 observable,那么什么事情也不会发生,所以我们将同时解释创建和订阅。

empty

empty 创建一个空的序列。它仅发送 .Completed 消息。

example("empty") {
    let emptySequence = Observable<Int>.empty()

    let subscription = emptySequence
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- empty example ---
Completed

never

never 创建一个序列,该序列永远不会发送消息,.Completed 消息也不会发送。

example("never") {
    let neverSequence = Observable<Int>.never()

    let subscription = neverSequence
        .subscribe { _ in
            print("This block is never called.")
        }
}

运行结果:

--- never example ---

just

just 代表只包含一个元素的序列。它将向订阅者发送两个消息,第一个消息是其中元素的值,另一个是 .Completed

example("just") {
    let singleElementSequence = Observable.just(32)

    let subscription = singleElementSequence
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- just example ---
Next(32)
Completed

sequenceOf

sequenceOf 通过固定数目的元素创建一个序列

example("sequenceOf") {
    let sequenceOfElements/* : Observable<Int> */ = Observable.of(0,1,2,3,4,5,6,7,8,9)

    let subscription = sequenceOfElements
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- sequenceOf example ---
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Next(6)
Next(7)
Next(8)
Next(9)
Completed

toObservable

toObservable 在一个数组的基础上创建一个序列

example("toObservable") {
    let sequenceFromArray = [1,5].toObservable()

    let subscription = sequenceFromArray
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- toObservable example ---
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Completed

create

create 使用 Swift 闭包来创建一个序列。该例子中,创建了 just 操作符的自定义版本。

example("create") {
    let myJust = { (singleElement: Int) -> Observable<Int> in
        return Observable.create { observer in
            observer.on(.Next(singleElement))
            observer.on(.Completed)

            return nopdisposable.instance
        }
    }

    let subscription = myJust(5)
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- create example ---
Next(5)
Completed

generate

generate 创建的序列可以自己生成它的值,并且在之前值的基础上来判断什么时候结束。

example("generate") {
    let generated = Observable.generate(
        initialState: 0,condition: { $0 < 3 },iterate: { $0 + 1 }
    )

    let subscription = generated
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- generate example ---
Next(0)
Next(1)
Next(2)
Completed

error

创建一个不发送任何 item 的 Observable,以 error 中指

example("error") {
    let error = NSError(domain: "Test",code: -1,userInfo: nil)

    let erroredSequence = Observable<Int>.error(error)

    let subscription = erroredSequence
        .subscribe { event in
            print(event)
        }
}

运行结果:

--- error example ---
Error(Error Domain=Test Code=-1 "(null)")

deferred

直到 observer 订阅之后才创建 Observable,并且为每一个 observer 创建一个全新的 Observable
do not create the Observable until the observer subscribes,and create a fresh Observable for each observer

更多相关内容请查看 reactive.io

example("deferred") {
    let deferredSequence: Observable<Int> = Observable.deferred {
        print("creating")
        return Observable.create { observer in
            print("emmiting")
            observer.on(.Next(0))
            observer.on(.Next(1))
            observer.on(.Next(2))

            return nopdisposable.instance
        }
    }

    _ = deferredSequence
        .subscribe { event in
            print(event)
         }

    _ = deferredSequence
        .subscribe { event in
            print(event)
         }
}

运行结果:

--- deferred example ---
creating
emmiting
Next(0)
Next(1)
Next(2)
creating
emmiting
Next(0)
Next(1)
Next(2)

在 RxCocoa 库中还有很多其他非常有用的方法,例如:

  • rx_observe 存在于所有 NSObject 子类中,封装了 KVO
  • rx_tap 存在于 button 中,封装了 @IBActions
  • rx_notification 封装了 NotificationCenter

Subjects

Subject 可以看成是一个桥梁或者代理,在某些ReactiveX实现中,它同时充当了 Observer 和 Observable 的角色。因为它是一个Observer,它可以订阅一个或多个 Observable;又因为它是一个 Observable,它可以转发它收到(Observe)的数据,也可以发射新的数据。

辅助函数:

func writeSequencetoConsole<O: ObservableType>(name: String,sequence: O) -> disposable {
    return sequence
        .subscribe { e in
            print("Subscription: \(name),event: \(e)")
        }
}

PublishSubject

PublishSubject 只会把在订阅发生的时间点之后来自原始Observable的数据发射给观察者。

example("PublishSubject") { let disposeBag = DisposeBag() let subject = PublishSubject<String>() writeSequencetoConsole("1",sequence: subject).adddisposableto(disposeBag) subject.on(.Next("a")) subject.on(.Next("b")) writeSequencetoConsole("2",sequence: subject).adddisposableto(disposeBag) subject.on(.Next("c")) subject.on(.Next("d")) }

运行结果:

--- PublishSubject example ---
Subscription: 1,event: Next(a)
Subscription: 1,event: Next(b)
Subscription: 1,event: Next(c)
Subscription: 2,event: Next(c)
Subscription: 1,event: Next(d)
Subscription: 2,event: Next(d)

ReplaySubject

ReplaySubject 会发射所有来自原始Observable的数据给观察者,无论它们是何时订阅的。当一个新的 observer 订阅了一个 ReplaySubject 之后,他将会收到当前缓存在 buffer 中的数据和这之后产生的新数据。在下面的例子中,缓存大小为 1 所以 observer 将最多能够收到订阅时间点之前的一个数据。例如,Subscription: 2 能够收到消息 "b",而这个消息是在他订阅之前发送的,但是没有办法收到消息 "a" 因为缓存的容量小于 2

example("ReplaySubject") { let disposeBag = DisposeBag() let subject = ReplaySubject<String>.create(bufferSize: 1) writeSequencetoConsole("1",sequence: subject).adddisposableto(disposeBag) subject.on(.Next("c")) subject.on(.Next("d")) }

运行结果:

--- ReplaySubject example ---  
Subscription: 1,event: Next(a)  
Subscription: 1,event: Next(b)  
Subscription: 2,event: Next(b)  
Subscription: 1,event: Next(c)  
Subscription: 2,event: Next(c)  
Subscription: 1,event: Next(d)  
Subscription: 2,event: Next(d)

BehaviorSubject

当观察者订阅 BehaviorSubject 时,它开始发射原始 Observable 最近发射的数据(如果此时还没有收到任何数据,它会发射一个默认值),然后继续发射其它任何来自原始Observable的数据。

example("BehaviorSubject") { let disposeBag = DisposeBag() let subject = BehaviorSubject(value: "z") writeSequencetoConsole("1",sequence: subject).adddisposableto(disposeBag) subject.on(.Next("c")) subject.on(.Next("d")) subject.on(.Completed) }

运行结果:

--- BehaviorSubject example ---
Subscription: 1,event: Next(z)
Subscription: 1,event: Next(b)
Subscription: 2,event: Next(d)
Subscription: 1,event: Completed
Subscription: 2,event: Completed

Variable

Variable 封装了 BehaviorSubject。使用 variable 的好处是 variable 将不会显式的发送 Error 或者 Completed。在 deallocated 的时候,Variable 会自动的发送 complete 事件。

example("Variable") {
    let disposeBag = disposeBag()
    let variable = Variable("z")
    writeSequencetoConsole("1",sequence: variable.asObservable()).adddisposableto(disposeBag)
    variable.value = "a"
    variable.value = "b"
    writeSequencetoConsole("2",sequence: variable.asObservable()).adddisposableto(disposeBag)
    variable.value = "c"
    variable.value = "d"
}

运行结果:

--- Variable example ---
Subscription: 1,event: Completed

变换操作

下面列出了可用于对 Observable 发射的数据执行变换操作的各种操作符。

map / select

对序列的每一项都应用一个函数来变换 Observable 发射的数据序列

更多相关内容请查看 reactive.io

example("map") {
    let originalSequence = Observable.of(1,3)

    _ = originalSequence
        .map { number in
            number * 2
        }
        .subscribe { print($0) }
}

运行结果:

--- map example ---
Next(2)
Next(4)
Next(6)
Completed

flatMap

将每个 Obserable 发射的数据变换为 Observable 的集合,然后将其 “拍扁”(降维 flatten)成一个 Observable。

更多相关内容请查看 reactive.io

example("flatMap") {
    let sequenceInt = Observable.of(1,3)

    let sequenceString = Observable.of("A","B","C","D","E","F","--")

    _ = sequenceInt
        .flatMap { (x:Int) -> Observable<String> in
            print("from sequenceInt \(x)")
            return sequenceString
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- flatMap example ---
from sequenceInt 1
Next(A)
Next(B)
Next(C)
Next(D)
Next(E)
Next(F)
Next(--)
from sequenceInt 2
Next(A)
Next(B)
Next(C)
Next(D)
Next(E)
Next(F)
Next(--)
from sequenceInt 3
Next(A)
Next(B)
Next(C)
Next(D)
Next(E)
Next(F)
Next(--)
Completed

scan

对 Observable 发射的每一项数据应用一个函数,然后按顺序依次发射每一个值

更多相关内容请查看 reactive.io

example("scan") { let sequencetoSum = Observable.of(0,5) _ = sequencetoSum .scan(0) { acum,elem in acum + elem } .subscribe { print($0) } }

运行结果:

--- scan example ---
Next(0)
Next(1)
Next(3)
Next(6)
Next(10)
Next(15)
Completed

过滤操作

从源 Observable 中选择特定的数据发送

filter

只发送 Observable 中通过特定测试的数据

更多相关内容请查看 reactive.io

example("filter") {
    let subscription = Observable.of(0,9)
        .filter {
            $0 % 2 == 0
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- filter example ---
Next(0)
Next(2)
Next(4)
Next(6)
Next(8)
Completed

distinctUntilChanged

过滤掉连续重复的数据

更多相关内容请查看 reactive.io

example("distinctUntilChanged") { let subscription = Observable.of(1,4) .distinctUntilChanged() .subscribe { print($0) } }

运行结果:

--- distinctUntilChanged example ---
Next(1)
Next(2)
Next(3)
Next(1)
Next(4)
Completed

take

仅发送 Observable 的前 n 个数据项

更多相关内容请查看 reactive.io

example("take") { let subscription = Observable.of(1,6) .take(3) .subscribe { print($0) } }

运行结果:

--- take example ---
Next(1)
Next(2)
Next(3)
Completed

结合操作(Combination operators)

将多个 Observable 结合成一个 Observable

startWith

在数据序列的开头增加一些数据

更多相关内容请查看 reactive.io

example("startWith") { let subscription = Observable.of(4,9) .startWith(3) .startWith(2) .startWith(1) .startWith(0) .subscribe { print($0) } }

运行结果:

--- startWith example ---
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Next(6)
Next(7)
Next(8)
Next(9)
Completed

combineLatest

当两个 Observables 中的任何一个发射了一个数据时,通过一个指定的函数组合每个Observable发射的最新数据(一共两个数据),然后发射这个函数的结果

更多相关内容请查看 reactive.io

example("combineLatest 1") {
    let intOb1 = PublishSubject<String>()
    let intOb2 = PublishSubject<Int>()

    _ = Observable.combineLatest(intOb1,intOb2) {
        "\($0) \($1)"
        }
        .subscribe {
            print($0)
        }

    intOb1.on(.Next("A"))

    intOb2.on(.Next(1))

    intOb1.on(.Next("B"))

    intOb2.on(.Next(2))
}

运行结果:

--- combineLatest 1 example ---
Next(A 1)
Next(B 1)
Next(B 2)

为了能够产生结果,两个序列中都必须保证至少有一个元素

example("combineLatest 2") {
    let intOb1 = Observable.just(2)
    let intOb2 = Observable.of(0,4)

    _ = Observable.combineLatest(intOb1,intOb2) {
            $0 * $1
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- combineLatest 2 example ---
Next(0)
Next(2)
Next(4)
Next(6)
Next(8)
Completed

Combine latest 有超过 2 个参数的版本

example("combineLatest 3") {
    let intOb1 = Observable.just(2)
    let intOb2 = Observable.of(0,3)
    let intOb3 = Observable.of(0,intOb2,intOb3) {
            ($0 + $1) * $2
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- combineLatest 3 example ---
Next(0)
Next(5)
Next(10)
Next(15)
Next(20)
Completed

Combinelatest 可以作用于不同数据类型的序列

example("combineLatest 4") {
    let intOb = Observable.just(2)
    let stringOb = Observable.just("a")

    _ = Observable.combineLatest(intOb,stringOb) {
            "\($0) " + $1
        }
        .subscribe {
            print($0)
    }
}

运行结果:

--- combineLatest 4 example ---
Next(2 a)
Completed

combineLatest 方法可以在 Array 上使用,数组元素类型必须遵循 ObservableType 协议
数组中的元素类型必须为 Observables

example("combineLatest 5") {
    let intOb1 = Observable.just(2)
    let intOb2 = Observable.of(0,3)
    let intOb3 = Observable.of(0,4)

    _ = [intOb1,intOb3].combineLatest { intArray -> Int in
            Int((intArray[0] + intArray[1]) * intArray[2])
        }
        .subscribe { (event: Event<Int>) -> Void in
            print(event)
        }
}

withLatestFrom

Merges two observable sequences into one observable sequence by using latest element from the second sequence every time when self emitts an element.

将两个 Observable 序列合并为一个。每当 self 队列发射一个元素时,从第二个序列中取出最新的一个值。

example("withLatestFrom") { let subjectA = PublishSubject<String>() let subjectB = PublishSubject<String>() subjectA .withLatestFrom(subjectB) .subscribeNext({ (data) in print(data) }) subjectA.onNext("a1") subjectB.onNext("b1") subjectA.onNext("a2") subjectA.onNext("a3") subjectB.onNext("b2") subjectA.onNext("a4") }

运行结果:

--- withLatestFrom example ---
b1
b1
b2

zip

使用一个函数组合多个Observable发射的数据集合,然后再发射这个结果(从序列中依次取数据)

更多相关内容请查看 reactive.io

example("zip 1") {
    let intOb1 = PublishSubject<String>()
    let intOb2 = PublishSubject<Int>()

    _ = Observable.zip(intOb1,intOb2) {
        "\($0) \($1)"
        }
        .subscribe {
            print($0)
        }

    intOb1.on(.Next("A"))

    intOb2.on(.Next(1))

    intOb1.on(.Next("B"))

    intOb1.on(.Next("C"))

    intOb2.on(.Next(2))
}

运行结果:

--- zip 1 example ---
Next(A 1)
Next(B 2)
example("zip 2") {
    let intOb1 = Observable.just(2)

    let intOb2 = Observable.of(0,4)

    _ = Observable.zip(intOb1,intOb2) {
            $0 * $1
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- zip 2 example ---
Next(0)
Completed
example("zip 3") {
    let intOb1 = Observable.of(0,1)
    let intOb2 = Observable.of(0,intOb3) {
            ($0 + $1) * $2
        }
        .subscribe {
            print($0)
        }
}

运行结果:

--- zip 3 example ---
Next(0)
Next(2)
Completed

merge

合并多个 Observables 的组合成一个

更多相关内容请查看 reactive.io

example("merge 1") {
    let subject1 = PublishSubject<Int>()
    let subject2 = PublishSubject<Int>()

    _ = Observable.of(subject1,subject2)
        .merge()
        .subscribeNext { int in
            print(int)
        }

    subject1.on(.Next(20))
    subject1.on(.Next(40))
    subject1.on(.Next(60))
    subject2.on(.Next(1))
    subject1.on(.Next(80))
    subject1.on(.Next(100))
    subject2.on(.Next(1))
}

运行结果:

--- merge 1 example ---
20
40
60
1
80
100
1
example("merge 2") {
    let subject1 = PublishSubject<Int>()
    let subject2 = PublishSubject<Int>()

    _ = Observable.of(subject1,subject2)
        .merge(maxConcurrent: 2)
        .subscribe {
            print($0)
        }

    subject1.on(.Next(20))
    subject1.on(.Next(40))
    subject1.on(.Next(60))
    subject2.on(.Next(1))
    subject1.on(.Next(80))
    subject1.on(.Next(100))
    subject2.on(.Next(1))
}

运行结果:

--- merge 2 example ---
Next(20)
Next(40)
Next(60)
Next(1)
Next(80)
Next(100)
Next(1)

switchLatest

将一个发射多个 Observables 的 Observable 转换成另一个单独的 Observable,后者发射那些 Observables 最近发射的数据项

Switch 订阅一个发射多个 Observables 的 Observable。它每次观察那些 Observables 中的一个,Switch 返回的这个Observable取消订阅前一个发射数据的 Observable,开始发射最近的Observable 发射的数据。注意:当原始 Observable 发射了一个新的 Observable 时(不是这个新的 Observable 发射了一条数据时),它将取消订阅之前的那个 Observable。这意味着,在后来那个 Observable 产生之后到它开始发射数据之前的这段时间里,前一个 Observable 发射的数据将被丢弃

更多相关内容请查看 reactive.io

example("switchLatest") {
    let var1 = Variable(0)

    let var2 = Variable(200)

    // var3 is like an Observable<Observable<Int>>
    let var3 = Variable(var1.asObservable())

    let d = var3
        .asObservable()
        .switchLatest()
        .subscribe {
            print($0)
        }

    var1.value = 1
    var1.value = 2
    var1.value = 3
    var1.value = 4

    var3.value = var2.asObservable()

    var2.value = 201

    var1.value = 5
    var1.value = 6
    var1.value = 7
}

运行结果:

--- switchLatest example ---
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(200)
Next(201)
Completed

Error Handling Operators

下面的操作符帮助我们从 Observable 发射的 error 通知做出响应或者从错误中恢复。

catchError

收到 Error 通知之后,转而发送一个没有错误的序列。

更多相关内容请查看 reactive.io

example("catchError 1") {
    let sequenceThatFails = PublishSubject<Int>()
    let recoverySequence = Observable.of(100,200,300,400)

    _ = sequenceThatFails
        .catchError { error in
            return recoverySequence
        }
        .subscribe {
            print($0)
        }

    sequenceThatFails.on(.Next(1))
    sequenceThatFails.on(.Next(2))
    sequenceThatFails.on(.Next(3))
    sequenceThatFails.on(.Next(4))
    sequenceThatFails.on(.Error(NSError(domain: "Test",code: 0,userInfo: nil)))
}

运行结果:

--- catchError 1 example ---
Next(1)
Next(2)
Next(3)
Next(4)
Next(100)
Next(200)
Next(300)
Next(400)
Completed
example("catchError 2") {
    let sequenceThatFails = PublishSubject<Int>()

    _ = sequenceThatFails
        .catchErrorJustReturn(100)
        .subscribe {
            print($0)
        }

    sequenceThatFails.on(.Next(1))
    sequenceThatFails.on(.Next(2))
    sequenceThatFails.on(.Next(3))
    sequenceThatFails.on(.Next(4))
    sequenceThatFails.on(.Error(NSError(domain: "Test",userInfo: nil)))
}

运行结果:

--- catchError 2 example ---
Next(1)
Next(2)
Next(3)
Next(4)
Next(100)
Completed

retry

如果原始 Observable 遇到错误,重新订阅,心里默念,不会出错不会出错…

更多相关内容请查看 reactive.io

example("retry") {
    var count = 1 // bad practice,only for example purposes
    let funnyLookingSequence = Observable<Int>.create { observer in
        let error = NSError(domain: "Test",userInfo: nil)
        observer.on(.Next(0))
        observer.on(.Next(1))
        observer.on(.Next(2))
        if count < 2 {
            observer.on(.Error(error))
            count += 1
        }
        observer.on(.Next(3))
        observer.on(.Next(4))
        observer.on(.Next(5))
        observer.on(.Completed)

        return nopdisposable.instance
    }

    _ = funnyLookingSequence
        .retry()
        .subscribe {
            print($0)
        }
}

运行结果:

--- retry example ---
Next(0)
Next(1)
Next(2)
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Completed

Observable Utility Operators

下面的操作符可以当做一个工具集,方便操作 Observable

subscribe

更多相关内容请查看 reactive.io

example("subscribe") { let sequenceOfInts = PublishSubject<Int>() _ = sequenceOfInts .subscribe { print($0) } sequenceOfInts.on(.Next(1)) sequenceOfInts.on(.Completed) }

运行结果:

--- subscribe example ---
Next(1)
Completed

下面是几个 subscribe 操作符的变体

subscribeNext

example("subscribeNext") { let sequenceOfInts = PublishSubject<Int>() _ = sequenceOfInts .subscribeNext { print($0) } sequenceOfInts.on(.Next(1)) sequenceOfInts.on(.Completed) }

运行结果:

--- subscribeNext example ---
1

subscribeCompleted

example("subscribeCompleted") { let sequenceOfInts = PublishSubject<Int>() _ = sequenceOfInts .subscribeCompleted { print("It's completed") } sequenceOfInts.on(.Next(1)) sequenceOfInts.on(.Completed) }

运行结果:

--- subscribeCompleted example ---
It's completed

subscribeError

example("subscribeError") {
    let sequenceOfInts = PublishSubject<Int>()

    _ = sequenceOfInts
        .subscribeError { error in
            print(error)
        }

    sequenceOfInts.on(.Next(1))
    sequenceOfInts.on(.Error(NSError(domain: "Examples",userInfo: nil)))
}

运行结果:

--- subscribeError example ---
Error Domain=Examples Code=-1 "(null)"

doOn

注册一个操作来监听事件的生命周期
(register an action to take upon a variety of Observable lifecycle events)

更多相关内容请查看 reactive.io

example("doOn") { let sequenceOfInts = PublishSubject<Int>() _ = sequenceOfInts .doOn { print("Intercepted event \($0)") } .subscribe { print($0) } sequenceOfInts.on(.Next(1)) sequenceOfInts.on(.Completed) }

运行结果:

--- doOn example ---
Intercepted event Next(1)
Next(1)
Intercepted event Completed
Completed

条件和布尔操作(Conditional and Boolean Operators)

下面的操作符可用于根据条件发射或变换 Observables,或者对它们做布尔运算:

takeuntil

当第二个 Observable 发送数据之后,丢弃第一个 Observable 在这之后的所有消息。

更多相关内容请查看 reactive.io

example("takeuntil") {
    let originalSequence = PublishSubject<Int>()
    let whenThisSendsNextWorldStops = PublishSubject<Int>()

    _ = originalSequence
        .takeuntil(whenThisSendsNextWorldStops)
        .subscribe {
            print($0)
        }

    originalSequence.on(.Next(1))
    originalSequence.on(.Next(2))
    originalSequence.on(.Next(3))
    originalSequence.on(.Next(4))

    whenThisSendsNextWorldStops.on(.Next(1))

    originalSequence.on(.Next(5))
}

运行结果:

--- takeuntil example ---
Next(1)
Next(2)
Next(3)
Next(4)
Completed

takeWhile

发送原始 Observable 的数据,直到一个特定的条件为 false

更多相关内容请查看 reactive.io

example("takeWhile") {

    let sequence = PublishSubject<Int>()

    _ = sequence
        .takeWhile { int in
            int < 4
        }
        .subscribe {
            print($0)
        }

    sequence.on(.Next(1))
    sequence.on(.Next(2))
    sequence.on(.Next(3))
    sequence.on(.Next(4))
    sequence.on(.Next(5))
}

运行结果:

--- takeWhile example ---
Next(1)
Next(2)
Next(3)
Completed

算数和聚合(Mathematical and Aggregate Operators)

concat

合并两个或者以上的 Observable 的消息,并且这些消息的发送时间不会交叉。(队列先后顺序不会交叉)

更多相关内容请查看 reactive.io

example("concat") {
    let var1 = BehaviorSubject(value: 0)
    let var2 = BehaviorSubject(value: 200)

    // var3 is like an Observable<Observable<Int>>
    let var3 = BehaviorSubject(value: var1)

    let d = var3
        .concat()
        .subscribe {
            print($0)
        }

    var1.on(.Next(1))
    var1.on(.Next(2))
    var1.on(.Next(3))
    var1.on(.Next(4))

    var3.on(.Next(var2))

    var2.on(.Next(201))

    var1.on(.Next(5))
    var1.on(.Next(6))
    var1.on(.Next(7))
    var1.on(.Completed)

    var2.on(.Next(202))
    var2.on(.Next(203))
    var2.on(.Next(204))
}

运行结果:

--- concat example ---
Next(0)
Next(1)
Next(2)
Next(3)
Next(4)
Next(5)
Next(6)
Next(7)
Next(201)
Next(202)
Next(203)
Next(204)

reduce

按顺序对Observable发射的每项数据应用一个函数并发射最终的值。
Reduce 操作符对原始 Observable 发射数据的第一项应用一个函数,然后再将这个函数的返回值与第二项数据一起传递给函数,以此类推,持续这个过程知道原始Observable发射它的最后一项数据并终止,此时 Reduce 返回的 Observable 发射这个函数返回的最终值。与数组序列的 reduce 操作类似。

更多相关内容请查看 reactive.io

example("reduce") { _ = Observable.of(0,9) .reduce(0,accumulator: +) .subscribe { print($0) } }

运行结果:

--- reduce example ---
Next(45)
Completed
iOS开发者交流群:①446310206 ②446310206

代码地址: 加入我们学习

RxSwift使用教程大全 韩俊强的博客的更多相关文章

  1. ios – RxSwift:返回一个带有错误的新observable

    我有一个函数返回BoolObservable,具体取决于它是否正常.解决方法返回包含单个元素的可观察序列.相反,你应该使用这样的东西:Create方法从指定的subscribe方法实现创建一个可观察的序列.在你的情况下:Anonymousdisposable是在您想要中断的情况下调用的操作.假设您离开视图控制器或应用程序需要完成该服务,您不再需要再调用此请求.它非常适合视频上传或更大的内容.您可以

  2. ios – RxSwift:使用rx_refreshing进行uirefreshcontrol

    我正在使用UIRefreshControl变量绑定来重新加载数据.然而,它正在起作用,以下对我来说是错误的:1)我知道RXCocoa扩展中有一个rx_refreshing变量,但我无法让它在这个上下文中工作.2)我绑定答案两次.一旦我加载视图控制器,当UIRefreshControl刷新时再次加载.3)我检查UIRefreshControl是否令人耳目一新的部分看起来很尴尬.感觉它是否违背了使用反应的目的?

  3. ios – 将UIApplicationDelegate方法转换为RxSwift Observables

    得到打印然后我在RxCocoa的_RXDelegateProxy_类中得到以下崩溃:有谁知道问题可能是什么?或者有没有人成功实现过像rx_applicationDidBecomeActive这样的东西?

  4. Swift-ReactiveCocoa3.0二SignalProducer 2

    lift运算符|>内部也是调用了lift方法,作用是把原producer的结果transform完返回新的类型/值,再封装成新的producer返回。只有在第一个producer销毁后才会响应第二个producer。之后,每当其中一个再sendNext,都会在next回调zipwith压缩两个信号,每当两个都sendNext一次才回在next回调一次。例子:sampleOn采样,当sampleOn的信号sendNext一次,就取一次producer1的最新一次sendNext的值进行next回调takeu

  5. 如何在Swift中调用C函数

    “,选择Yes,创建SwiftCallC-Bridging-Header.h文件给工程建立一个C语言文件。跟上述步骤3类似,只不过这里选择的是C文件,这里的文件取名为CFile.c,同时自动生成CFile.h文件开始编写代码。在SwiftCallC-Bridging-Header.h文件中声明C函数,这里是voidcallCDemo()在CFile.c中定义这个函数在main.swift中调用这个C函数编译运行

  6. Swift--UINavigationController

    代码目录AppDelegate.swiftViewController.swiftNext.swift效果图

  7. Swift如何取得View所属的ViewController

    从VC取得View很容易,但有些情况下我们需要从View反向获取VC.不过在一些特殊的场合,Cocoa库帮我们想的很周到,比如在自定义view过渡动画的时候:系统在回调我们的animateTransition方法时,会传入一个context参数,从它我们可以轻松取得参与动画的toView,fromView以及它们对应的VC:但不是所有情况系统都会帮你考虑的这么周到,所以有时候还得需要自己从View

  8. 在实践中应用 RxSwift

    注:本文基于Swift3。Swift大会上有一场POP的分享,Demo地址RxPagination。摘要在上一篇在实践中应用RxSwift1-使用Result传递值中,我们解决了error的处理,但当我们处理一段很长的事件流时,会发现有很多不重要的代码,比如传递Error。在Rx中,map和flatMap是最常用的,我们添加一些小工具。以此表示这个方法是用在flatMap上的。关于为什么FlatMap中会有filter,您可以参考这篇文章用更Swifty的代码遍历数据。

  9. RxSwift使用教程

    前言RxSwift是Swift函数响应式编程的一个开源库,由Github的ReactiveX组织开发,维护。RxSwift的目的是让让数据/事件流和异步任务能够更方便的序列化处理,能够使用Swift进行响应式编程目前,RxSwift在Github上收到了5000+Star,600+fork。RxSwift的核心思想和这个类似。RxSwift的核心是想是Observablesequence,Observable表示可监听或者可观察,也就是说RxSwift的核心思想是可监听的序列。

  10. Swift 3.0 中 GCD 相关函数的语法

    在Swift3.0中,一些c语言的API调用相比以前发生了较大的变化。包括GCD这个经常使用的框架。在Swift

随机推荐

  1. Swift UITextField,UITextView,UISegmentedControl,UISwitch

    下面我们通过一个demo来简单的实现下这些控件的功能.首先,我们拖将这几个控件拖到storyboard,并关联上相应的属性和动作.如图:关联上属性和动作后,看看实现的代码:

  2. swift UISlider,UIStepper

    我们用两个label来显示slider和stepper的值.再用张图片来显示改变stepper值的效果.首先,这三个控件需要全局变量声明如下然后,我们对所有的控件做个简单的布局:最后,当slider的值改变时,我们用一个label来显示值的变化,同样,用另一个label来显示stepper值的变化,并改变图片的大小:实现效果如下:

  3. preferredFontForTextStyle字体设置之更改

    即:

  4. Swift没有异常处理,遇到功能性错误怎么办?

    本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请发送邮件至dio@foxmail.com举报,一经查实,本站将立刻删除。

  5. 字典实战和UIKit初探

    ios中数组和字典的应用Applicationschedule类别子项类别名称优先级数据包contactsentertainment接触UIKit学习用Swift调用CocoaTouchimportUIKitletcolors=[]varbackView=UIView(frame:CGRectMake(0.0,0.0,320.0,CGFloat(colors.count*50)))backView

  6. swift语言IOS8开发战记21 Core Data2

    上一话中我们简单地介绍了一些coredata的基本知识,这一话我们通过编程来实现coredata的使用。还记得我们在coredata中定义的那个Model么,上面这段代码会加载这个Model。定义完方法之后,我们对coredata的准备都已经完成了。最后强调一点,coredata并不是数据库,它只是一个框架,协助我们进行数据库操作,它并不关心我们把数据存到哪里。

  7. swift语言IOS8开发战记22 Core Data3

    上一话我们定义了与coredata有关的变量和方法,做足了准备工作,这一话我们来试试能不能成功。首先打开上一话中生成的Info类,在其中引用头文件的地方添加一个@objc,不然后面会报错,我也不知道为什么。

  8. swift实战小程序1天气预报

    在有一定swift基础的情况下,让我们来做一些小程序练练手,今天来试试做一个简单地天气预报。然后在btnpressed方法中依旧增加loadWeather方法.在loadWeather方法中加上信息的显示语句:运行一下看看效果,如图:虽然显示出来了,但是我们的text是可编辑状态的,在storyboard中勾选Editable,再次运行:大功告成,而且现在每次单击按钮,就会重新请求天气情况,大家也来试试吧。

  9. 【iOS学习01】swift ? and !  的学习

    如果不初始化就会报错。

  10. swift语言IOS8开发战记23 Core Data4

    接着我们需要把我们的Rest类变成一个被coredata管理的类,点开Rest类,作如下修改:关键字@NSManaged的作用是与实体中对应的属性通信,BinaryData对应的类型是NSData,CoreData没有布尔属性,只能用0和1来区分。进行如下操作,输入类名:建立好之后因为我们之前写的代码有些地方并不适用于coredata,所以编译器会报错,现在来一一解决。

返回
顶部