
以下內(nèi)容翻譯自 ReactiveSwift 官方文檔中的 Basic Operators 部分
Basic Operators
本文解釋了RAC中一些最常用的操作,并包括演示其用法的示例。
請注意到關(guān)于本文的“操作”指的是轉(zhuǎn)換signals和signal producers的函數(shù),并不是常用的swift基本操作。換句話說,這些是由RAC提供的用于處理事件流的可組合原語。
Map
map 用于轉(zhuǎn)換事件流中的值,并用結(jié)果創(chuàng)建新流。
func rac_mapping() -> Void {
let (signal, observer) = Signal<String, NoError>.pipe()
signal
.map { string in string.uppercased() } // 小寫轉(zhuǎn)大寫
.observeValues { value in print(value) }
observer.send(value: "a") // Print A
observer.send(value: "b") // Print B
observer.send(value: "c") // Print C
}

Filter
filter 用于過濾不滿足條件的值。
func rac_filtering() -> Void {
let (signal, observer) = Signal<Int, NoError>.pipe()
signal
.filter { number in number % 2 == 0 } // 過濾某些值
.observeValues { value in print(value) }
observer.send(value: 1) // Not printed
observer.send(value: 2) // Prints 2
observer.send(value: 3) // Not printed
observer.send(value: 4) // prints 4
}

Reduce
reduce 用于事件流的值聚合為單個(gè)組合值,請注意到最終值僅僅在輸入流完成后才發(fā)送。(個(gè)人理解即調(diào)用 sendCompleted 后才能 observeValues)
func rac_reduce() -> Void {
let (signal, observer) = Signal<Int, NoError>.pipe()
signal
.reduce(1) { $0 * $1 }
.observeValues { (value) in
print(value)}
observer.send(value: 1) // nothing printed
observer.send(value: 2) // nothing printed
observer.send(value: 3) // nothing printed
observer.sendCompleted() // prints 6
}

collect
collect 用于將事件流的值聚合為單個(gè)數(shù)組值,請注意到最終值僅僅在輸入流完成后才發(fā)送。(個(gè)人理解即調(diào)用 sendCompleted 后才能 observeValues)
func rac_collect() -> Void {
let (signal, observer) = Signal<Int, NoError>.pipe()
signal
.collect()
.observeValues { value in print(value) }
observer.send(value: 1) // nothing printed
observer.send(value: 2) // nothing printed
observer.send(value: 3) // nothing printed
observer.sendCompleted() // prints [1, 2, 3]
}
CombineLatest
combineLatest 用于將兩個(gè)(或多個(gè))事件流組合為最新流,所得到的流將僅在每個(gè)輸入都發(fā)送至少一個(gè)值之后才發(fā)送其第一次值。之后,任何輸入上的新值將導(dǎo)致輸出上的新值。
func rac_combineLatest() -> Void {
let (numbersSignal, numbersObserver) = Signal<Int, NoError>.pipe()
let (lettersSignal, lettersObserver) = Signal<String, NoError>.pipe()
// let signal = numbersSignal.combineLatest(with: lettersSignal)
let signal = Signal.combineLatest(numbersSignal, lettersSignal)
signal.observeValues { next in print("Next: \(next)") }
signal.observeCompleted { print("Completed") }
numbersObserver.send(value: 0) // nothing printed
numbersObserver.send(value: 1) // nothing printed
lettersObserver.send(value: "A") // prints (1, A)
numbersObserver.send(value: 2) // prints (2, A)
numbersObserver.sendCompleted() // nothing printed
lettersObserver.send(value: "B") // prints (2, B)
lettersObserver.send(value: "C") // prints (2, C)
lettersObserver.sendCompleted() // prints "Completed"
}

Zip
zip 成對地連接兩個(gè)(或多個(gè))事件流的值,即多個(gè)輸入流第N個(gè)元組的元素對應(yīng)于輸入流的第N個(gè)元素,這意味著在每個(gè)輸入發(fā)送至少N個(gè)值之前,不能發(fā)送輸出流的第N個(gè)值。
func rac_zipping() -> Void {
let (numbersSignal, numbersObserver) = Signal<Int, NoError>.pipe()
let (lettersSignal, lettersObserver) = Signal<String, NoError>.pipe()
// let signal = numbersSignal.zip(with: lettersSignal)
let signal = Signal.zip(numbersSignal, lettersSignal)
signal.observeValues { next in print("Next: \(next)") }
signal.observeCompleted { print("Completed") }
numbersObserver.send(value: 0) // nothing printed
numbersObserver.send(value: 1) // nothing printed
lettersObserver.send(value: "A") // prints (0, A)
numbersObserver.send(value: 2) // nothing printed
numbersObserver.sendCompleted() // nothing printed
lettersObserver.send(value: "B") // prints (1, B)
lettersObserver.send(value: "C") // prints (2, C) & "Completed"
}

Flatten
.Merge
.merge 策略會(huì)立即將內(nèi)部事件流的每個(gè)值轉(zhuǎn)發(fā)到外部事件流,在外部事件流或任何內(nèi)部事件流上發(fā)送的任何錯(cuò)誤都會(huì)將立即在 flatten 事件流上發(fā)送,并且會(huì)終止 flatten 事件流。
func rac_merge() -> Void {
let (lettersSignal, lettersObserver) = Signal<String, NoError>.pipe()
let (numbersSignal, numbersObserver) = Signal<String, NoError>.pipe()
let (signal, observer) = Signal<Signal<String, NoError>, NoError>.pipe()
signal.flatten(.merge).observeValues { print($0) }
observer.send(value: lettersSignal)
observer.send(value: numbersSignal)
observer.sendCompleted()
lettersObserver.send(value: "a") // prints "a"
numbersObserver.send(value: "1") // prints "1"
lettersObserver.send(value: "b") // prints "b"
numbersObserver.send(value: "2") // prints "2"
lettersObserver.send(value: "c") // prints "c"
numbersObserver.send(value: "3") // prints "3"
}

.Concat
.merge 策略會(huì)序列化內(nèi)部事件流,按順序執(zhí)行 send 進(jìn)來的事件流,后一個(gè)事件流必須等待前一個(gè)事件流的完成才開始執(zhí)行。
func rac_concat() -> Void {
let (lettersSignal, lettersObserver) = Signal<String, NoError>.pipe()
let (numbersSignal, numbersObserver) = Signal<String, NoError>.pipe()
let (signal, observer) = Signal<Signal<String, NoError>, NoError>.pipe()
signal.flatten(.concat).observeValues { print($0) }
observer.send(value: lettersSignal)
observer.send(value: numbersSignal)
observer.sendCompleted()
numbersObserver.send(value: "1") // nothing printed
lettersObserver.send(value: "a") // prints "a"
lettersObserver.send(value: "b") // prints "b"
numbersObserver.send(value: "2") // nothing printed
lettersObserver.send(value: "c") // prints "c"
lettersObserver.sendCompleted() // prints "1, 2"
numbersObserver.send(value: "3") // prints "3"
numbersObserver.sendCompleted()
}

.latest
.latest 策略僅從最新輸入事件流轉(zhuǎn)發(fā)值或錯(cuò)誤。
func rac_latest() -> Void {
let (lettersSignal, lettersObserver) = Signal<String, NoError>.pipe()
let (numbersSignal, numbersObserver) = Signal<String, NoError>.pipe()
let (signal, observer) = Signal<Signal<String, NoError>, NoError>.pipe()
signal.flatten(.latest).observeValues { print($0) }
observer.send(value: lettersSignal) // nothing printed
numbersObserver.send(value: "1") // nothing printed
lettersObserver.send(value: "a") // prints "a"
lettersObserver.send(value: "b") // prints "b"
numbersObserver.send(value: "2") // nothing printed
observer.send(value: numbersSignal) // nothing printed
lettersObserver.send(value: "c") // nothing printed
numbersObserver.send(value: "3") // prints "3"
}
FlatMapError
flatMapError 可以捕獲可能在輸入事件流上發(fā)生的任何失敗,然后再開啟一個(gè)新的 SignalProducer。(以下代碼與官方文檔不同,做了些許修改,個(gè)人覺得更好體現(xiàn) flatMapError 的作用)
func rac_flatMapError() -> Void {
let (signal, observer) = Signal<String, NSError>.pipe()
let producer = SignalProducer(signal)
let error = NSError(domain: "domain", code: 2, userInfo: nil)
producer
.flatMapError { (err) -> SignalProducer<String, NoError> in
switch err.code {
case 0:
print("code is 0")
return SignalProducer<String, NoError>(value:"code is 0")
default:
return SignalProducer<String, NoError>(value:"code is unknow")
}}
.startWithValues { (value) in
print(value)
}
observer.send(value: "First") // prints "First"
observer.send(value: "Second") // prints "Second"
observer.send(error: error) // prints "code is unknow"
}
MapError
mapError 將事件流中的任何錯(cuò)誤轉(zhuǎn)換為新錯(cuò)誤。
func rac_mapError() -> Void {
enum CustomError: String, Error {
case foo = "Foo Error"
case bar = "Bar Error"
case other = "Other Error"
}
let (signal, observer) = Signal<String, NSError>.pipe()
signal
.mapError { (error: NSError) -> CustomError in
switch error.domain {
case "com.example.foo":
return .foo
case "com.example.bar":
return .bar
default:
return .other
}
}
.observeFailed { error in
print(error.rawValue)
}
observer.send(error: NSError(domain: "com.example.foo", code: 42, userInfo: nil)) // prints "Foo Error"
}
最后
RAC 官方原文還有 Promote、Retrying、SignalProducer.attempt(_:) 這幾個(gè)基本操作,但是這里木有介紹,可以在 ReactiveSwift 文檔 查看詳細(xì)用法,以上所有圖片均源自 ReactiveSwift 文檔。