Reputation: 3713
Here is a pseudo code of what I need to achieve:
func apiRequest1() -> Future<ResultType1, Error> { ... }
func apiRequest2() -> Future<ResultType2, Error> { ... }
func transform(res1: ResultType1, res2: ResultType2) -> ResultType3 { ... }
func combinedApiRequests() -> Future<ResultType3, Error> {
(resultType1, resultType2) = execute apiRequest1() and apiRequest2() asynchronously
resultType3 = transform(resultType1, resultType2)
return a Future publisher with resultType3
}
How would combinedApiRequests()
look?
Upvotes: 0
Views: 1316
Reputation: 49590
There's no need to return a Future
publisher. Future
publisher is a specific publisher, but as far as a downstream is concerned, a publisher is defined by its output and failure types. Instead, return a AnyPublisher<ResultType3, Error>
.
Zip
is a publisher that waits for all results to arrive to emit a value. This is probably what you'd need (more on this later). This is how your function could look:
func combinedApiRequests() -> AnyPublisher<ResultType3, Error> {
Publishers.Zip(apiRequest1, apiRequest2)
.map { transform(res1: $0, res2: $1) }
.eraseToAnyPublisher()
}
There is also CombineLatest
publisher. For the first result from each upstream, it behaves the same as Zip
, but for subsequent results it differs. In your case, it doesn't matter since Future
is a one-shot publisher, but if the upstream publishers emitted multiple values, then you'd have to decide for your specific use case whether to use Zip
- which always waits for all upstreams to emit a value before it emits a combined value, or CombineLatest
- which emits with each new upstream value and combines it with the latest for other upstreams.
Upvotes: 2