Tar*_*ras 3 reactive-cocoa swift reactive-swift combine
如何ReactiveSwift/ReactiveCocoa使用Combine框架重写代码?我附上了截图combinePrevious来自文档的含义。
let producer = SignalProducer<Int, Never>([1, 2, 3]).combinePrevious(0)
producer.startWithValues { value in
print(value) // print: (0, 1), (1, 2), (2, 3)
}
Run Code Online (Sandbox Code Playgroud)
我不是完全熟悉ReactiveSwift/ReactiveCocoa,但根据你的描述,你可以使用.scan,这似乎是一个比combinePrevious.
它需要一个初始结果——你可以把它变成一个元组——以及一个包含存储值和当前值的闭包,并返回一个新的存储值——在你的情况下,一个元组(previous, current):
let producer = [1,2,3].publisher
.scan((0,0)) { ($0.1, $1) }
producer.sink {
print($0)
}
Run Code Online (Sandbox Code Playgroud)
这些是我想出的自定义运算符(称为withPrevious)。有两种重载,一种是初始前值所在的位置,另一种是nil您提供初始前值的位置,这样您就不必处理可选项。
extension Publisher {
/// Includes the current element as well as the previous element from the upstream publisher in a tuple where the previous element is optional.
/// The first time the upstream publisher emits an element, the previous element will be `nil`.
///
/// let range = (1...5)
/// cancellable = range.publisher
/// .withPrevious()
/// .sink { print ("(\($0.previous), \($0.current))", terminator: " ") }
/// // Prints: "(nil, 1) (Optional(1), 2) (Optional(2), 3) (Optional(3), 4) (Optional(4), 5) ".
///
/// - Returns: A publisher of a tuple of the previous and current elements from the upstream publisher.
func withPrevious() -> AnyPublisher<(previous: Output?, current: Output), Failure> {
scan(Optional<(Output?, Output)>.none) { ($0?.1, $1) }
.compactMap { $0 }
.eraseToAnyPublisher()
}
/// Includes the current element as well as the previous element from the upstream publisher in a tuple where the previous element is not optional.
/// The first time the upstream publisher emits an element, the previous element will be the `initialPreviousValue`.
///
/// let range = (1...5)
/// cancellable = range.publisher
/// .withPrevious(0)
/// .sink { print ("(\($0.previous), \($0.current))", terminator: " ") }
/// // Prints: "(0, 1) (1, 2) (2, 3) (3, 4) (4, 5) ".
///
/// - Parameter initialPreviousValue: The initial value to use as the "previous" value when the upstream publisher emits for the first time.
/// - Returns: A publisher of a tuple of the previous and current elements from the upstream publisher.
func withPrevious(_ initialPreviousValue: Output) -> AnyPublisher<(previous: Output, current: Output), Failure> {
scan((initialPreviousValue, initialPreviousValue)) { ($0.1, $1) }.eraseToAnyPublisher()
}
}
Run Code Online (Sandbox Code Playgroud)
Cocoacasts 有一个很好的例子:
https://cocoacasts.com/combine-essentials-combining-publishers-with-combine-zip-operator
zip 运算符可用于创建发布者,该发布者发出前一个元素和发布者发出的当前元素。我们将同一个发布者传递给 Publishers.Zip 结构的初始化程序两次,但将 dropFirst 运算符应用于第二个发布者。这仅仅意味着第二个发布者不会发出原始发布者的第一个元素。
import Combine
let numbers = [1, 2, 3, 4, 5].publisher
Publishers.Zip(numbers, numbers.dropFirst(1))
Run Code Online (Sandbox Code Playgroud)
用法:
import Combine
let numbers = [1, 2, 3, 4, 5].publisher
Publishers.Zip(numbers, numbers.dropFirst(1))
.sink(receiveValue: { values in
print(values)
})
// (1, 2)
// (2, 3)
// (3, 4)
// (4, 5)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1261 次 |
| 最近记录: |