RxSwift 文档:操作符

just 、 from 和 of


justfrom 都能够将元素转化为 Observable 但是他们有本质的区别:

just

创建 Observable 发出唯一的一个元素just 操作符将某一个元素转换为 Observable

示例:

1
2
3
4
5
6
7
let oJust = Observable.just([1, 2, 3, 4, 5])
oJust.subscribe(onNext: {
print($0)
})
.dispose()

// [1, 2, 3, 4, 5]

相当于

1
2
3
4
5
let oJust = Observable<Array<Int>>.create { (observer) -> Disposable in
observer.onNext([1, 2, 3, 4, 5])
observer.onCompleted()
return Disposables.create()
}

from

将其他类型或者数据结构转换为 Observable 。当你在使用 Observable 时,如果能够直接将其他类型转换为 Observable,这将是非常省事的。from 操作符就提供了这种功能。

示例:

1
2
3
4
5
6
7
8
9
10
11
let oFrom = Observable.from([1, 2, 3, 4, 5])
oFrom.subscribe(onNext: {
print($0)
})
.dispose()

// 1
// 2
// 3
// 4
// 5

相当于

1
2
3
4
5
6
7
8
9
let oFrom = Observable<Int>.create { (observer) -> Disposable in
observer.onNext(1)
observer.onNext(2)
observer.onNext(3)
observer.onNext(4)
observer.onNext(5)
observer.onCompleted()
return Disposables.create()
}

将一个值转化为 Observable 可以用 Observable.from(optional: <_?>) 方法。

1
2
let optional: Int? = 1
let value = Observable.from(optional: optional)

相当于

1
2
3
4
5
6
7
8
let optional: Int? = 1
let value = Observable<Int>.create { observer in
if let element = optional {
observer.onNext(element)
}
observer.onCompleted()
return Disposables.create()
}

of

能将多个元素转化为 Observable

1
2
3
4
5
6
7
8
9
10
Observable.of(1, 2, 3, 4, 5).subscribe(onNext: {
print($0)
})
.dispose()

// 1
// 2
// 3
// 4
// 5

concat、combineLatest 和 zip


concat

让两个或多个 Observables 按顺序串连起来。

concat 操作符将多个 Observables 按顺序串联起来,当前一个 Observable 元素发送完毕后,后一个 Observable 才可以开始发出元素。

concat 将等待前一个 Observable 产生完成事件后,才对后一个 Observable 进行订阅。如果后一个是“热” Observable ,在它前一个 Observable 产生完成事件前,所产生的元素将不会被发送出来。

startWith 和它十分相似。但是 startWith 不是在后面添加元素,而是在前面插入元素。

merge 和它也是十分相似。**merge 并不是将多个 Observables 按顺序串联起来,而是将他们合并到一起,不需要 Observables 按先后顺序发出元素。**

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
let disposeBag = DisposeBag()

let subject1 = BehaviorSubject(value: "🍎")
let subject2 = BehaviorSubject(value: "🐶")

let variable = Variable(subject1)

variable.asObservable()
.concat()
.subscribe { print($0) }
.disposed(by: disposeBag)

subject1.onNext("🍐")
subject1.onNext("🍊")

variable.value = subject2

subject2.onNext("I would be ignored")
subject2.onNext("🐱")

subject1.onCompleted()

subject2.onNext("🐭")

// next(🍎)
// next(🍐)
// next(🍊)
// next(🐱)
// next(🐭)

zip

通过一个函数将多个 Observables 的元素组合起来,然后将每一个组合的结果发出来。

zip 操作符将多个(最多不超过8个) Observables 的元素通过一个函数组合起来,然后将这个组合的结果发出来。它会严格的按照序列的索引数进行组合。例如,返回的 Observable 的第一个元素,是由每一个源 Observables 的第一个元素组合出来的。它的第二个元素 ,是由每一个源 Observables 的第二个元素组合出来的。它的第三个元素 ,是由每一个源 Observables 的第三个元素组合出来的,以此类推。它的元素数量等于源 Observables 中元素数量最少的那个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let disposeBag = DisposeBag()
let first = PublishSubject<String>()
let second = PublishSubject<String>()

Observable.zip(first, second) { $0 + $1 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

first.onNext("1")
second.onNext("A")
first.onNext("2")
second.onNext("B")
second.onNext("C")
second.onNext("D")
first.onNext("3")
first.onNext("4")
first.onNext("5") // 并没有输出

// 1A
// 2B
// 3C
// 4D

combineLatest(可与 zip 比较学习)

当多个 Observables 中任何一个发出一个元素,就发出一个元素。这个元素是由这些 Observables 中最新的元素,通过一个函数组合起来的。

combineLatest 操作符将多个 Observables 中最新的元素通过一个函数组合起来,然后将这个组合的结果发出来。这些源 Observables 中任何一个发出一个元素,他都会发出一个元素(前提是,这些 Observables 曾经发出过元素)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let disposeBag = DisposeBag()

let first = PublishSubject<String>()
let second = PublishSubject<String>()

Observable.combineLatest(first, second) { $0 + $1 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

first.onNext("1")
second.onNext("A")
first.onNext("2")
second.onNext("B")
second.onNext("C")
second.onNext("D")
first.onNext("3")
first.onNext("4")

// 1A
// 2A
// 2B
// 2C
// 2D
// 3D
// 4D

flatMap 和 flatMapLatest


flatMap

Observable 的元素转换成其他的 Observable,然后将这些 Observables 合并。

flatMap 操作符将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。 然后将这些 Observables 的元素合并之后再发送出来。

这个操作符是非常有用的,例如,当 Observable 的元素本生拥有其他的 Observable 时,你可以将所有子 Observables 的元素发送出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let disposeBag = DisposeBag()
let first = BehaviorSubject(value: "👦🏻")
let second = BehaviorSubject(value: "🅰️")
let variable = Variable(first)

variable.asObservable()
.flatMap { $0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

first.onNext("🐱")
variable.value = second
second.onNext("🅱️")
first.onNext("🐶")

// 👦🏻
// 🐱
// 🅰️
// 🅱️
// 🐶

flatMapLatest

Observable 的元素转换成其他的 Observable,然后取这些 Observables最新的一个

flatMapLatest 操作符将源 Observable 的每一个元素应用一个转换方法,将他们转换成 Observables。一旦转换出一个新的 Observable,就只发出它的元素,旧的 Observables 的元素将被忽略掉。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
let disposeBag = DisposeBag()
let first = BehaviorSubject(value: "👦🏻")
let second = BehaviorSubject(value: "🅰️")
let variable = Variable(first)

variable.asObservable()
.flatMapLatest { $0 }
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

first.onNext("🐱")
variable.value = second
second.onNext("🅱️")
first.onNext("🐶")



// 👦🏻
// 🐱
// 🅰️
// 🅱️

scan


持续的将 Observable 的每一个元素应用一个函数,然后发出每一次函数返回的结果。

scan 操作符将对第一个元素应用一个函数,将结果作为第一个元素发出。然后,将结果作为参数填入到第二个元素的应用函数中,创建第二个元素。以此类推,直到遍历完全部的元素。

这种操作符在其他地方有时候被称作是 accumulator

1
2
3
4
5
6
7
8
9
10
11
12
let disposeBag = DisposeBag()

Observable.of(10, 100, 1000)
.scan(1) { aggregateValue, newValue in
aggregateValue + newValue
}
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

// 11
// 111
// 1111

materialize 和 dematerialize


materialize

将任何 Observable 转换为其事件的可观察者。

1
2
3
4
5
6
7
8
9
10
11
12
Observable
.range(start: 1, count: 3)
.materialize()
.subscribe(onNext: {
print($0)
})
.disposed(by: bag)

// next(1)
// next(2)
// next(3)
// completed

作为对比

1
2
3
4
5
6
7
8
9
10
Observable
.range(start: 1, count: 3)
.subscribe(onNext: {
print($0)
})
.disposed(by: bag)

// 1
// 2
// 3

dematerialize

dematerialize 操作符将 materialize 转换后的元素还原

take 、 takeLast 和 elementAt


take

仅仅从 Observable 中发出头 n 个元素。通过 take 操作符你可以只发出头 n 个元素。并且忽略掉后面的元素,直接结束序列。

1
2
3
4
5
6
7
8
9
10
let disposeBag = DisposeBag()

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.take(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

// 🐱
// 🐰
// 🐶

takeLast

仅仅从 Observable 中发出尾部 n 个元素,通过 takeLast 操作符你可以只发出尾部 n 个元素。并且忽略掉前面的元素。

1
2
3
4
5
6
7
8
9
10
let disposeBag = DisposeBag()

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.takeLast(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

// 🐸
// 🐷
// 🐵

elementAt

只发出 Observable 中的第 n 个元素,elementAt 操作符将拉取 Observable 序列中指定索引数的元素,然后将它作为唯一的元素发出。

1
2
3
4
5
6
7
8
let disposeBag = DisposeBag()

Observable.of("🐱", "🐰", "🐶", "🐸", "🐷", "🐵")
.elementAt(3)
.subscribe(onNext: { print($0) })
.disposed(by: disposeBag)

// 🐸