以下内容翻译自 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 官方原文还有 Promote
、Retrying
、SignalProducer.attempt(_:)
这几个基本操作,但是这里木有介绍,可以在 ReactiveSwift 文档 查看详细用法,以上所有图片均源自 ReactiveSwift 文档。
网友评论