1

In RxSwift you can create a reactive function something like this:

func aFunc() -> Observable<Void> {
    return Observable.create({ emitter in
        let disposable = Observable
            .combineLatest(someObservable,
                           someOtherObservable)
                .subscribe(onNext: { responseA, responseB in
                    // do stuff
                })

                return Disposables.create {
                    disposable.dispose()
                }
            })
        }

In Combine you can achieve similar results using Future:

func aFunc() -> Future<Void, Error> {
    return Future { promise in
        somePublisher
            .combineLatest(someObservable,
                           someOtherObservable)
                .sink{ responseA, responseB in
                    // do stuff
                }
            })
        }

The thing I don't quite get is that the Future doesn't seem to return its equivalent of RxSwift's

return Disposables.create {
    disposable.dispose()
}

How is standard practice to handle disposing/cancelling of publishers in a Future?

I tried simply adding:

_ = somePublisher...

But then the publisher isn't kept alive and will simply not activate at all. Should I just hook on .store(in: &cancellables) to the end of the publisher. But them, when do I cancel those cancellables? Or is there some way of returning cancellables, like in RxSwift? What am I missing?

Joakim Sjöstedt
  • 824
  • 2
  • 9
  • 18
  • 1
    I don't understand what kind of `Publisher` you are trying to create. Does it only publish *once*? If not, then a `Future` is not appropriate. And even if it does, why do you need a `Future` when you can manipulate the `combineLatest` publisher instead? – Sweeper Jul 04 '23 at 12:44
  • The only thing that's relevant in this question is how combine should handle publishers inside of the Future. RxSwift does it using return Disposables.create { disposable.dispose() } How does it work with combine? – Joakim Sjöstedt Jul 04 '23 at 12:55
  • 1
    I don't think Combine is designed to "handle publishers inside of the `Future`". Why would you ever want to "nest" publishers like that, when you can just operate on the "inner" publisher directly? This sounds very much like an [XY Problem](http://xyproblem.info/). `Future` is not the same as `Observable.create`. – Sweeper Jul 04 '23 at 12:58
  • "Future is not the same as Observable.create" Really? Aren't they sort of the same? – Joakim Sjöstedt Jul 04 '23 at 13:06
  • 1
    No. `Future` is a very specific publisher that either publishes one single element and then completes, or throws an error. `Observable.create` is a *lot* more general than that. – Sweeper Jul 04 '23 at 13:12
  • 1
    Perhaps putting it this way makes it clearer why they are not the same - the closure that `Observable.create` takes is used to implement the `Observable.subscribe(_:)` method, but the closure that `Future` takes is used to implement the `Publisher.receive(subscriber:)` method, which I don't think is a thing in RxSwift. The implementation of the `Publisher.subscribe(_:)` on the other hand, is an extension method and so cannot be changed. – Sweeper Jul 04 '23 at 13:34
  • 1
    More importantly, a Future is eager and *can't* be disposed/cancelled once it starts. That's why it’s creator doesn’t have a way to cancel it. I agree that the RxSwift code is nonsensical. Just use the Observables you have. – Daniel T. Jul 05 '23 at 01:47
  • Thanks for clearing all of that up, I guess I have to find another way to restructure my streams to combine publishers. – Joakim Sjöstedt Jul 05 '23 at 09:25

1 Answers1

1

The answer is, you don't. A Combine Future is like an RxSwift Single that can't be canceled once it starts.

Daniel T.
  • 32,821
  • 6
  • 50
  • 72