Swift 合并.repeat
Swift Combine .repeat
我想创建一个重复功能,使用 Combine 在我的代码中创建一个循环。我注意到 Combine 没有通过这个伟大的 repo 重复发布者:https://github.com/freak4pc/rxswift-to-combine-cheatsheet。这是我编写的用于重复 2 个状态的代码。如何将其简化为更易读的内容或创建我自己的重复函数?
toggleShouldDisplay = Just<Void>(())
.delay(for: 2, scheduler:RunLoop.main)
.map({ _ in
self.shouldDisplay = true
self.didChange.send(())
})
.delay(for: 2, scheduler: RunLoop.main)
.map({ _ in
self.shouldDisplay = false
self.didChange.send(())
})
.setFailureType(to: NSError.self)
.tryMap({ _ in
throw NSError()
})
.retry(.max) // I might hit Int.max if I reduce the delays
.sink(receiveValue: { _ in
//Left empty
})
.retry(_:)
运算符的真正目的是用于重试可能会失败的操作,例如网络请求。听起来您需要一个计时器。幸运的是,从 Xcode 11 beta 2 开始,Apple 已将 Publisher 支持添加到 Foundation 中的 Timer
class。
关于您的实施的另一条评论:我假设此代码用于 BindableObject
,因为您正在访问 didChange
。既然 didChange
可以是任何一种 Publisher
,为什么不用你的 shouldDisplay
属性 作为 Publisher
?
final class MyModel: BindableObject {
var didChange: CurrentValueSubject<Bool, Never> { shouldDisplaySubject }
var shouldDisplay: Bool { shouldDisplaySubject.value }
private let shouldDisplaySubject = CurrentValueSubject<Bool, Never>(false)
private var cancellables: Set<AnyCancellable> = []
init() {
startTimer()
}
private func startTimer() {
Timer.publish(every: 2, on: .main, in: .default)
.autoconnect()
.scan(false) { shouldDisplay, _ in
!shouldDisplay
}
.assign(to: \.value, on: shouldDisplaySubject)
.store(in: &cancellables)
}
}
您可以这样使用 Timer.Publisher
:
toggleShouldDisplay = Timer.publisher(every: 2, on: .main, in: .default)
.autoconnect()
.sink {
self.shouldDisplay = !self.shouldDisplay
self.didChange.send(())
}
autconnect()
让 Timer
在您使用 sink(_:)
订阅后立即开始。
我想创建一个重复功能,使用 Combine 在我的代码中创建一个循环。我注意到 Combine 没有通过这个伟大的 repo 重复发布者:https://github.com/freak4pc/rxswift-to-combine-cheatsheet。这是我编写的用于重复 2 个状态的代码。如何将其简化为更易读的内容或创建我自己的重复函数?
toggleShouldDisplay = Just<Void>(())
.delay(for: 2, scheduler:RunLoop.main)
.map({ _ in
self.shouldDisplay = true
self.didChange.send(())
})
.delay(for: 2, scheduler: RunLoop.main)
.map({ _ in
self.shouldDisplay = false
self.didChange.send(())
})
.setFailureType(to: NSError.self)
.tryMap({ _ in
throw NSError()
})
.retry(.max) // I might hit Int.max if I reduce the delays
.sink(receiveValue: { _ in
//Left empty
})
.retry(_:)
运算符的真正目的是用于重试可能会失败的操作,例如网络请求。听起来您需要一个计时器。幸运的是,从 Xcode 11 beta 2 开始,Apple 已将 Publisher 支持添加到 Foundation 中的 Timer
class。
关于您的实施的另一条评论:我假设此代码用于 BindableObject
,因为您正在访问 didChange
。既然 didChange
可以是任何一种 Publisher
,为什么不用你的 shouldDisplay
属性 作为 Publisher
?
final class MyModel: BindableObject {
var didChange: CurrentValueSubject<Bool, Never> { shouldDisplaySubject }
var shouldDisplay: Bool { shouldDisplaySubject.value }
private let shouldDisplaySubject = CurrentValueSubject<Bool, Never>(false)
private var cancellables: Set<AnyCancellable> = []
init() {
startTimer()
}
private func startTimer() {
Timer.publish(every: 2, on: .main, in: .default)
.autoconnect()
.scan(false) { shouldDisplay, _ in
!shouldDisplay
}
.assign(to: \.value, on: shouldDisplaySubject)
.store(in: &cancellables)
}
}
您可以这样使用 Timer.Publisher
:
toggleShouldDisplay = Timer.publisher(every: 2, on: .main, in: .default)
.autoconnect()
.sink {
self.shouldDisplay = !self.shouldDisplay
self.didChange.send(())
}
autconnect()
让 Timer
在您使用 sink(_:)
订阅后立即开始。