通过RxSwift了解zip和combineLatest之间的序列参数差异



我使用了两个函数。第一个combineLatest:

enum Weather {
case cloudy
case sunny
}
let left: Observable<Weather> = Observable.of(.sunny, .cloudy, .cloudy, .sunny)
let right = Observable.of("Lisbon", "Copenhagen", "London", "Madrid", "Vienna")
let observable = Observable.combineLatest(left, right) { weather, city in
return "It's (weather) in (city)"
}
_ = observable.subscribe(onNext: { value in
print(value)
})

输出:

里斯本阳光明媚里斯本多云哥本哈根多云哥本哈根多云伦敦多云伦敦阳光明媚马德里阳光明媚维也纳阳光明媚

zip:

enum Weather {
case cloudy
case sunny
}
let left: Observable<Weather> = Observable.of(.sunny, .cloudy, .cloudy, .sunny)
let right = Observable.of("Lisbon", "Copenhagen", "London", "Madrid", "Vienna")
let observable = Observable.zip(left, right) { weather, city in
return "It's (weather) in (city)"
}
_ = observable.subscribe(onNext: { value in
print(value)
})

输出:

里斯本阳光明媚哥本哈根多云伦敦多云马德里阳光明媚

天气怎么样?我知道zip只是将值一一映射,若同一个索引并没有值,它就跳过它。但如何理解combineLatest呢?

combineLatest更容易理解(也更有用!(如果两个可观察器不立即发射元素。一个更容易理解的例子(我鼓励你尝试(是:

Observable.combineLatest(someUISwitch.rx.isOn, someUITextField.rx.text) { isOn, text in
return "Text: (text ?? ""), Switch is on: (isOn)"
}.subscribe(onNext: { value in
print(value)
}).disposed(by: disposeBag)

尝试在UI中添加UISwitchUITextField。现在尝试在文本字段中输入一些文本,同时尝试切换开关。您将看到,每当这两个值中的一个发生变化时,也就是说,当任何一个可观测值发出新值时,它们的组合值(由传递给combineLatest的闭包组合而成(都会由组合的可观测值发射。

更一般地,由combineLatest产生的可观测值在所有可观测值首次发出值时发出其第一个值,并且当任何可观测值发出值时,发出后续值。每当它发出一个值时,它发出的值都是通过组合所有可观测值发出的所有最新值来计算的。因此;组合最新";。

对于Observable.of示例,所有值都会立即发射,但combineLatest的行为就像leftright以交错顺序发射值,而left先发射。我已经尝试为您得到的输出添加注释。看看这是否有助于你理解。

(left emits sunny)
(right emits Lisbon)
It's sunny in Lisbon (the first values emitted by both observables)
(left emits cloudy)
It's cloudy in Lisbon
(right emits Copenhagen)
It's cloudy in Copenhagen
(left emits 2nd cloudy)
It's cloudy in Copenhagen
(right emits London)
It's cloudy in London
(left emits sunny)
It's sunny in London
(right emits Madrid)
It's sunny in Madrid
(right emits Vienna, since left ran out)
It's sunny in Vienna

另外,别忘了还有RxMarbles可以玩。

最新更新