了解 zip 和 combineLatest 与 RxSwift 之间序列参数的区别
Understanding difference between zip and combineLatest with RxSwift for sequence parameters
我用过两个功能。首先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 不立即 发射元素,则更容易理解(也更有用!)。一个更容易理解的例子(我鼓励你尝试)是:
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 中添加一个 UISwitch
和一个 UITextField
。现在尝试在文本字段中输入一些文本,并尝试切换开关。您会看到,每当这两个变化中的一个发生变化时,即当任一可观察对象发出新值时,它们的组合值(通过传递给 combineLatest
的闭包组合)将由组合的可观察对象发出。
更一般地说,由 combineLatest
生成的可观察对象在所有可观察对象首次发出一个值时发出其第一个值,并且在任何可观察对象发出一个值时发出后续值。每当它发出一个值时,它发出的值是通过组合所有 observables 发出的所有 latest 值来计算的。因此“结合最新”。
对于您的 Observable.of
示例,所有值都会立即发出,但 combineLatest
的行为就好像 left
和 right
以交错顺序发出值,并且 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 可以玩。
我用过两个功能。首先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 不立即 发射元素,则更容易理解(也更有用!)。一个更容易理解的例子(我鼓励你尝试)是:
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 中添加一个 UISwitch
和一个 UITextField
。现在尝试在文本字段中输入一些文本,并尝试切换开关。您会看到,每当这两个变化中的一个发生变化时,即当任一可观察对象发出新值时,它们的组合值(通过传递给 combineLatest
的闭包组合)将由组合的可观察对象发出。
更一般地说,由 combineLatest
生成的可观察对象在所有可观察对象首次发出一个值时发出其第一个值,并且在任何可观察对象发出一个值时发出后续值。每当它发出一个值时,它发出的值是通过组合所有 observables 发出的所有 latest 值来计算的。因此“结合最新”。
对于您的 Observable.of
示例,所有值都会立即发出,但 combineLatest
的行为就好像 left
和 right
以交错顺序发出值,并且 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 可以玩。