Prefixing and concatenating前缀和链接
startWith
在一个可观察序列前面添加一个可观察元素
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
连接两个可观察的序列
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, 如下图所示
// 1
let left = PublishSubject<String>()
let right = PublishSubject<String>()
// 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
example(of: "combineLatest") {
let left = PublishSubject<String>()
let right = PublishSubject<String>()
// 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<String>()
let right = PublishSubject<String>()
// 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<String>()
let two = PublishSubject<String>()
let three = PublishSubject<String>()
let source = PublishSubject<Observable<String>>()
// 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
有些时候,您可能想要同时观察多个序列。这个时候我们就可以使用这个 combineLatest 操作符了,它会将多个序列联合成一个单独的序列。事实上,flatMapLatest 是 map 和 combineLatest 两个操作符的联合。
combineLatest会组合两个序列各自的最新值, 只会把各自的最新值输出
example(of:"combineLatest") {
let disposeBag = DisposeBag()
let number = PublishSubject<Int>()
let string = PublishSubject<String>()
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")
}