RxSwift|RxSwift - Combining Operators组合运算符(5)
Prefixing and concatenating前缀和链接
startWith
在一个可观察序列前面添加一个可观察元素
文章图片
屏幕快照 2017-08-15 下午3.43.55.png
example(of: "startWith") {
// 1 原始可观察序列
let numbers = Observable.of(2, 3, 4)
// 2 新加一个可观察序列的元素
let observable = numbers.startWith(1)
observable.subscribe(onNext: { value in
print(value)
})
}
打印1,2,3,4
contcat 连接两个可观察的序列
文章图片
屏幕快照 2017-08-15 下午3.48.26.png
let first = Observable.of(1, 2, 3)
let second = Observable.of(4, 5, 6)
let observable = Observable.concat([first, second])
observable.subscribe(onNext: { value in
print(value)
})
另外一种拼接的写法是使用可观察对象调用实例方法
let observable = first.concat(second)
merge
通过merge将多个Observables合并到一个Observables, 如下图所示
文章图片
屏幕快照 2017-08-15 下午4.33.08.png
// 1
let left = PublishSubject()
let right = PublishSubject()
// 2
let source = Observable.of(left.asObservable(), right.asObservable())
// 3
let observable = source.merge()
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 4
var leftValues = ["Berlin", "Munich", "Frankfurt"]
var rightValues = ["Madrid", "Barcelona", "Valencia"]
repeat {
if arc4random_uniform(2) == 0 {
if !leftValues.isEmpty {
left.onNext("Left:" + leftValues.removeFirst())
}
} else if !rightValues.isEmpty {
right.onNext("Right: " + rightValues.removeFirst())
}
} while !leftValues.isEmpty || !rightValues.isEmpty
// 5
disposable.dispose()
Combining elements
文章图片
屏幕快照 2017-08-16 上午9.50.41.png
example(of: "combineLatest") {
let left = PublishSubject()
let right = PublishSubject()
// 1
let observable = Observable.combineLatest(left, right, resultSelector:
{
lastLeft, lastRight in
"\(lastLeft) \(lastRight)"
})
let disposable = observable.subscribe(onNext: { value in
print("rs -> \(value)")
})// 2
print("> Sending a value to Left")
left.onNext("Hello,")
print("> Sending a value to Right")
right.onNext("world")
print("> Sending another value to Right")
right.onNext("RxSwift")
print("> Sending another value to Left")
left.onNext("Have a good day,")
disposable.dispose()
}
Switches
RxSwift带有两个主要的所谓“切换”运算符:amb(_ :)和switchLatest()。 它们都允许您通过在组合或源序列的事件之间切换来产生可观察序列。 这允许你
以确定用户在运行时接收的序列的事件。
- amb(_ :)运算符订阅左右可观察值。 它等待任何一个发出一个元素,然后取消订阅另一个元素。 之后,它只会从第一个主动观察者中获取元素。
let left = PublishSubject()
let right = PublishSubject()
// 1 这个不区分谁作为调用方, 写成`left.amb(right)`也可以
let observable = right.amb(left)
let disposable = observable.subscribe(onNext: { value in
print(value)
})
// 2 left先发出
left.onNext("Lisbon")
right.onNext("Copenhagen")
left.onNext("London")
left.onNext("Madrid")
right.onNext("Vienna")
disposable.dispose()
只会打印left发出的元素
Lisbon
London
Madrid
- switchLatest 只会观察当前最新的值, 当切换观察被对象的对象时, 新值被观察, 旧值不会被观察
example(of: "switchLatest") {
// 1 主题
let one = PublishSubject()
let two = PublishSubject()
let three = PublishSubject()
let source = PublishSubject()
// 2 观察源
let observable = source.switchLatest()
let disposable = observable.subscribe(onNext: { value in
print(value)
})// 3 把one当做当前的观察的对象, 其他的都不会被观察
source.onNext(one)
//会发出消息
one.onNext("Some text from sequence one")
//不会发出
two.onNext("Some text from sequence two")
//切换要观察的对象
source.onNext(two)
//会发出消息
two.onNext("More text from sequence two")
//目前被观察的是two, one不会发出消息
one.onNext("and also from sequence one")
//切换要观察的对象为three
source.onNext(three)
//不会发出
two.onNext("Why don't you seem me?")
//不会发出
one.onNext("I'm alone, help me")
//会发出
three.onNext("Hey it's three. I win.")
//再次切换到one
source.onNext(one)
//会发出
one.onNext("Nope. It's me, one!")
//销毁
disposable.dispose()
}
reduce
以某一个初始值和某一个运算符对序列里的元素一次进行运算
下面是一个累加运算, 返回最终的累加结果
example(of: "reduce") {
let source = Observable.of(1, 3, 5, 7, 9)
//累加, 第一个参数是累加的初始值, 此处设置为0,
//第二个参数是运算符, 此处是+
let observable = source.reduce(0, accumulator: +)
observable.subscribe(onNext: { value in
print(value)
})
}
累加, 结果为25
scan
累加, 返回每一次累加的结果
example(of: "scan") {
let source = Observable.of(1, 3, 5, 7, 9)
let observable = source.scan(0, accumulator: +)
observable.subscribe(onNext: { value in
print(value)
})
}
打印1, 4, 9, 16, 25
combineLatest 【RxSwift|RxSwift - Combining Operators组合运算符(5)】有些时候,您可能想要同时观察多个序列。这个时候我们就可以使用这个 combineLatest 操作符了,它会将多个序列联合成一个单独的序列。事实上,flatMapLatest 是 map 和 combineLatest 两个操作符的联合。
combineLatest会组合两个序列各自的最新值, 只会把各自的最新值输出
example(of:"combineLatest") {
let disposeBag = DisposeBag()
let number = PublishSubject()
let string = PublishSubject()
Observable.combineLatest(number, string) {
"\($0) \($1)"
}
.subscribe {
print($0)
}
.addDisposableTo(disposeBag)
//number的最新值是1, 但是string还没有最新值, 所以不会输出
number.onNext(1)
print("Nothing yet")
//此时number的最新值是1, string的最新值是A, 所以会输出1 A
string.onNext("A")
//此时number的最新值仍是1, 但是string的最新值已经被修改成了D, 所以会输出1 D
string.onNext("D")
//此时number的最新值又被修改成了2, string的最新值仍然是D, 所以会输出2 D
number.onNext(2)
//以此类推......
string.onNext("B")
number.onNext(3)
string.onNext("C")
}
推荐阅读
- RxSwift官方实例八(UITableVIew)
- RxSwift官方playground翻译
- RxSwift|RxSwift 条件和布尔操作符(Conditional and Boolean Operators)
- Dictionaries|Dictionaries And Identity Operators
- RxSwift-map
- Leetcode282.|Leetcode282. Expression Add Operators
- Rainbow:|Rainbow: Combining Improvements in Deep Reinforcement Learning
- RxDataSource/RxSwift配置tableView
- 框架学习RxSwift2.0|框架学习RxSwift2.0 Observable创建
- 函数响应式编程思想|函数响应式编程思想 & RxSwift 核心逻辑