How to combine 2 publishers and erase values to Void?

Viewed 2879

I have 2 publishers where I want to perform an action based on either response. I don't care about the values. I'm trying to do something like this:

var hasChangedPublisher: AnyPublisher<(Void, Void), Never> {
    Publishers.CombineLatest(
        preferences.publisher,
        state.$permissionStatus
    ).eraseToAnyPublisher()
}

If preferences.publisher fires first but not the other, I want to fire. If state.$permissionStatus fires but not the other, I want to fire. I don't really want to CombineLatest, but not sure how to fire if either emit.

Is there a way to produce an even if either fire but more elegantly erase its values?

3 Answers

You're looking for Merge instead of CombineLatest. Your code for this would look a bit like the following:

var hasChangedPublisher: AnyPublisher<Void, Never> {
  preferences.publisher
    .merge(state.$permissionStatus)
    .map({ _ in
      return () // transform to Void
    })
    .eraseToAnyPublisher()
}

Instead of CombineLatest, use Merge.

CombineLatest creates a tuple based on all the publishers that are combined. It is great, except, it will not fire at all until every one of the combined publishers has fired at least once. After that, it will fire once for every firing of any of its combined publishers - (merging the last value from each publisher into the tuple).

Merge, instead, just multiplexes all combined publishers together and generates a stream of events - containing a stream of single values from any of the combined publishers.

// transform to Void .map { _ in }

Related