Reputation: 289
I have a PassthroughSubject
which is connected to a ScrollView
and it emits while it scrolls. I want the subject to emit the current scroll value, but only once per second. I tried throttle
and debounce
, but they don't seem to be doing what I need.
Like this, I can see every time it emits while I'm scrolling, so my base setup of scroll detection is working well.
scrollSubject
.sink { value in
print(value)
}
.store(in: &subscription)
But when I try to use either of these:
.throttle(for: 1, scheduler: RunLoop.main, latest: false)
(tried latest: true
also)`
.debounce(for: 1, scheduler: RunLoop.main)
What happens is they are not emitting while I'm scrolling, only after I've stopped it emits the latest value. How is it possible to achieve the desire behaviour?
Upvotes: 1
Views: 1664
Reputation: 2916
What you are describing sounds like the sample
operator available in other reactive programming libraries. It can be implemented in this way like @Alexander is describing:
extension Publisher {
func sample(
every interval: TimeInterval,
on runLoop: RunLoop,
in mode: RunLoop.Mode
) -> AnyPublisher<Output, Failure> {
let timer = Timer.publish(every: interval, on: runLoop, in: mode)
.autoconnect()
.mapError { $0 as! Failure }
return combineLatest(timer)
.map(\.0)
.eraseToAnyPublisher()
}
}
Upvotes: 2