Home > database >  iOS Combine debounce fire manually
iOS Combine debounce fire manually

Time:09-16

I am using the debounce Operator of the iOS Combine Framework.

var subject = PassthroughSubject<Void, Never>()
var cancellable: Cancellable!
cancellable = subject
    .debounce(for: .seconds(0.1), scheduler: RunLoop.main)
    .sink {
        // doSomething
    }

Now I want to "fire the event" to doSomething before the timer (0.1 seconds) ends. Is there a method which can invoke this?

CodePudding user response:

In the functional approach you can interact with your value at any level of processing tree. In your case before debounce:

cancellable = subject
    .handleEvents(
        receiveOutput: { output in
            // this is called on each new send
            // like subject.send(())
        },
        receiveCompletion: { result in
            // this is called on send completion
            // like subject.send(completion: .finished)
            switch result {
            case .finished:
                print("ok")
            case .failure(let error):
                print("failure \(error)")
            }
        }
    )
    .debounce(for: .seconds(0.1), scheduler: RunLoop.main)
    .sink {
        // doSomething
    }

CodePudding user response:

The simplest way would be to use the handleEvents methods to manage any event through the pipeline. Although not the only one and more cool.

You could use two subscriptions to separate your logic. Besides for the first case where you don't want to have a delay you could take only the first value with first() or prefix(1).

I share an example with you:

import Foundation
import Combine

let subject = PassthroughSubject<Void, Never>()

// The shared one is optional, depending on the case. 
For heavy publishers which for example do network requests is a good practice.
let sharedSubject = subject.share() 

let normalCancellable = sharedSubject.first()
    .sink { print("Normal") }


let debouncedCancellable = sharedSubject
    .debounce(for: .seconds(0.3), scheduler: RunLoop.main)
    .sink { print("Debounced") }

subject.send()
subject.send()
subject.send()

Output

receive subscription: (PassthroughSubject)
request unlimited
receive value: (())
Normal
receive value: (())
receive value: (())
Debounced

  • Related