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)

// 🐸