① ReactiveSwift 官方文档翻译

作者 Tsui YuenHong 日期 2017-01-10
① ReactiveSwift 官方文档翻译

以下内容翻译自 ReactiveSwift 官方文档中的 Basic Operators 部分

Basic Operators

本文解释了RAC中一些最常用的操作,并包括演示其用法的示例。
请注意到关于本文的“操作”指的是转换signals和signal producers的函数,并不是常用的swift基本操作。换句话说,这些是由RAC提供的用于处理事件流的可组合原语。

Map

map 用于转换事件流中的值,并用结果创建新流。

func rac_mapping() -> Void {
let (signal, observer) = Signal<String, NoError>.pipe()
signal
.map { string in string.uppercased() } // 小写转大写
.observeValues { value in print(value) }
observer.send(value: "a") // Print A
observer.send(value: "b") // Print B
observer.send(value: "c") // Print C
}

map

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
}

filter

Reduce

reduce 用于事件流的值聚合为单个组合值,请注意到最终值仅仅在输入流完成后才发送。(个人理解即调用 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
}

reduce

collect

collect 用于将事件流的值聚合为单个数组值,请注意到最终值仅仅在输入流完成后才发送。(个人理解即调用 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 用于将两个(或多个)事件流组合为最新流,所得到的流将仅在每个输入都发送至少一个值之后才发送其第一次值。之后,任何输入上的新值将导致输出上的新值。

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"
}

combineLatest

Zip

zip 成对地连接两个(或多个)事件流的值,即多个输入流第N个元组的元素对应于输入流的第N个元素,这意味着在每个输入发送至少N个值之前,不能发送输出流的第N个值。

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"
}

zip

Flatten

.Merge

.merge 策略会立即将内部事件流的每个值转发到外部事件流,在外部事件流或任何内部事件流上发送的任何错误都会将立即在 flatten 事件流上发送,并且会终止 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"
}

flatten(.merge)

.Concat

.merge 策略会序列化内部事件流,按顺序执行 send 进来的事件流,后一个事件流必须等待前一个事件流的完成才开始执行。

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()
}

flatten(.concat)

.latest

.latest 策略仅从最新输入事件流转发值或错误。

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 可以捕获可能在输入事件流上发生的任何失败,然后再开启一个新的 SignalProducer。(以下代码与官方文档不同,做了些许修改,个人觉得更好体现 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 将事件流中的任何错误转换为新错误。

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 官方原文还有 PromoteRetryingSignalProducer.attempt(_:) 这几个基本操作,但是这里木有介绍,可以在 ReactiveSwift 文档 查看详细用法,以上所有图片均源自 ReactiveSwift 文档。