0

Like the title says I would like to make custom publisher that will basically function like deffered future. Normally when I want to encapsulate code in some Future, but want it to execute on subscription, I would need to write something like this:

Deffered {
    Future { promise in
    }
}

Now I was thinking of making custom publisher, something along the lines DefferedFuture that will have exact same functionality as Future, but will execute promise only on subscription?

MegaManX
  • 8,766
  • 12
  • 51
  • 83
  • Since that is exactly what deferred future does already, what new functionality do you need? – matt Dec 08 '21 at 21:29
  • I want to write it as one publisher, not Deffered { Future {} }, just NewDefferedFuture {}. – MegaManX Dec 08 '21 at 22:03

1 Answers1

2

The most obvious answer is this:

func single<Output, Failure>(_ promise: @escaping (@escaping (Result<Output, Failure>) -> Void) -> Void) -> Deferred<Future<Output, Failure>> where Failure: Error {
    Deferred {
        Future<Output, Failure>(promise)
    }
}

If it absolutely must be a type rather than a function then:

extension Publishers {
    struct Single<Output, Failure>: Publisher where Failure: Error {
        let promise: (@escaping (Result<Output, Failure>) -> Void) -> Void
        
        func receive<S>(subscriber: S) where S: Subscriber, Failure == S.Failure, Output == S.Input {
            Deferred { Future(promise) }
            .subscribe(subscriber)
        }
    }
}
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • For a more generic solution, you can use [Ian Keen's AnyPubliser extension](https://gist.github.com/IanKeen/934258d2d5193160391e14d25e54b084) which will allow you to emit more than one value before completing. Something Future doesn't allow. – Daniel T. Dec 10 '21 at 00:00
  • Thanks, it must be a type, second part solves it – MegaManX Dec 10 '21 at 10:46