文檔地址:Basic Operators
注意本文所提的『操作符』,指的是操作signals和signal producers的函數(shù),不是傳統(tǒng)編程語(yǔ)言里的操作符。換句話說(shuō),這些是用于處理事件流的基本元素。
本文將用事件流(event stream)指代Signal和SignalProducer。當(dāng)有分歧時(shí),會(huì)單獨(dú)指明類型。
本文將介紹:observe、on、lift、map、filter、reduce 六個(gè)操作符。
我翻譯的RAC4的文檔
ReactiveCocoa 4 官方文檔翻譯
ReactiveCocoa 4 文檔翻譯:基本操作符(一)
ReactiveCocoa 4 文檔翻譯:基本操作符(二)
ReactiveCocoa 4 文檔翻譯:框架組成介紹
ReactiveCocoa 4 文檔翻譯:兼容Objective-C
ReactiveCocoa 4 文檔翻譯--設(shè)計(jì)指南(一):事件的規(guī)范
ReactiveCocoa 4 文檔翻譯:設(shè)計(jì)指南(二):信號(hào)的規(guī)范
[翻譯]ReactiveCocoa 4 最佳實(shí)踐
對(duì)事件流產(chǎn)生副作用(Performing side effects with event streams)
觀察(Observation)
Signals可以通過(guò)<code> observe </code>函數(shù)進(jìn)行觀察。參數(shù)是一個(gè)<code> Observer </code>??梢杂^察到這個(gè)signal將來(lái)每次發(fā)送的事件。
<pre><code>
signal.observe(Signal.Observer { event in
switch event {
case let .Next(next):
print("Next: (next)")
case let .Failed(error):
print("Failed: (error)")
case .Completed:
print("Completed")
case .Interrupted:
print("Interrupted")
}
})
</code></pre>
這樣當(dāng)有<code> Next, Failed, Completed</code> 和<code> Interrupted </code>事件發(fā)生時(shí)就會(huì)觸發(fā)這些回調(diào)。
<pre><code>
signal.observeNext { next in
print("Next: (next)") }
signal.observeFailed { error in
print("Failed: (error)")}
signal.observeCompleted {
print("Completed") }
signal.observeInterrupted {
print("Interrupted")}
</code></pre>
你不必觀察所有類型,也可以只關(guān)注某個(gè)你關(guān)心的事件。
注入影響(Injecting effects)
可以通過(guò)<code> on </code>來(lái)觀察<code> SignalProducer </code>,即使沒(méi)有人訂閱也會(huì)被觸發(fā)。
<pre><code>
let producer = signalProducer
.on(started: {
print("Started")
}, event: { event in
print("Event: (event)")
}, failed: { error in
print("Failed: (error)")
}, completed: {
print("Completed")
}, interrupted: {
print("Interrupted")
}, terminated: {
print("Terminated")
}, disposed: {
print("Disposed")
}, next: { value in
print("Next: (value)")
})
</code></pre>
和<code> observe </code>相似,也可以只觀察你關(guān)注的某個(gè)事件。
需要提到的是<code> producer </code>要started后才會(huì)觸發(fā)。
可能很多人不了解什么是函數(shù)的副作用,可以參考下這篇:函數(shù)的副作用
操作符合成(Operator composition)
向上遷移
<code> Signal </code>的操作符可以通過(guò)<code> lift </code>函數(shù)向上遷移以在<code>SignalProducers</code>上使用。
這樣會(huì)產(chǎn)生一個(gè)新的SignalProducer,然后將操作符應(yīng)用到每個(gè)由它產(chǎn)生的Signal中。
轉(zhuǎn)換事件流(Transforming event streams)
以下這些操作符會(huì)將事件流轉(zhuǎn)換成一個(gè)新的事件流。
映射(Mapping)
<code> map </code>用于將一個(gè)事件流的值操作后的結(jié)果產(chǎn)生一個(gè)新的事件流。
<pre><code>
let (signal, observer) = Signal<String, NoError>.pipe()
signal
.map { string in string.uppercaseString }
.observeNext { next in print(next) }
observer.sendNext("a") // Prints A
observer.sendNext("b") // Prints B
observer.sendNext("c") // Prints C
</code></pre>
強(qiáng)烈推薦這個(gè)可以到這個(gè)網(wǎng)站看看:Interactive visualisation of the map operator。通過(guò)了圖案的方式來(lái)表達(dá)這個(gè)函數(shù)。
下圖表示的是將一個(gè)數(shù)字映射為它的10倍。如果一個(gè)事件流本里的值是1、2、3,經(jīng)過(guò)這個(gè)map后產(chǎn)生一個(gè)新的事件流,里面的值為10、20、30。
過(guò)濾(Filtering)
<code> filter </code>函數(shù)可以按照之前預(yù)設(shè)的條件過(guò)濾掉不滿足的值。
<pre><code>
let (signal, observer) = Signal<Int, NoError>.pipe()
signal
.filter { number in number % 2 == 0 }
.observeNext { next in print(next) }
observer.sendNext(1) // Not printed
observer.sendNext(2) // Prints 2
observer.sendNext(3) // Not printed
observer.sendNext(4) // prints 4
</code></pre>
下圖條件是x>10,最后剩下30,22,60
聚集(Aggregating)
<code> reduce </code>將事件里的值聚集后組合成一個(gè)值。要注意的是最后算出來(lái)的值直到輸入的流完成后才會(huì)被發(fā)送出去。
<pre><code>
let (signal, observer) = Signal<Int, NoError>.pipe()
signal .reduce(1) { $0 * $1 }
.observeNext { next in print(next) }
observer.sendNext(1) // nothing printed
observer.sendNext(2) // nothing printed
observer.sendNext(3) // nothing printed
observer.sendCompleted() // prints 6
</code></pre>
下圖展示的是輸入的值為1、2、3、4、5。合并規(guī)則是求和。在5發(fā)送出去事件完成后,新的事件流將運(yùn)算后求得的15發(fā)送出去。
歡迎關(guān)注我的微博:@沒(méi)故事的卓同學(xué)