Last active
January 27, 2022 10:01
-
-
Save piotrtobolski/b6fa065194935f2d083e96375e3ca432 to your computer and use it in GitHub Desktop.
Combine.Publisher.flatMap issue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Combine | |
enum MyError: Error { | |
case error | |
} | |
let subject1 = PassthroughSubject<Int, Error>() | |
let cancellable1 = subject1 | |
.print("before flatMap") | |
.flatMap { _ in | |
Fail<Int, Error>(error: MyError.error) | |
} | |
.print("after flatMap") | |
.sink { | |
print("completion: \($0)") | |
} receiveValue: { | |
print("receiveValue: \($0)") | |
} | |
print("Sending 1") | |
subject1.send(1) | |
print("Sending 2") | |
subject1.send(2) | |
print("Cancelling") | |
cancellable1.cancel() | |
print("Sending 3") | |
subject1.send(3) | |
extension Publisher { | |
func flatMap2<T, P>( | |
maxPublishers: Subscribers.Demand = .unlimited, | |
_ transform: @escaping (Self.Output) -> P | |
) -> AnyPublisher<T, Failure> | |
where T == P.Output, P : Publisher, Self.Failure == P.Failure { | |
flatMap(maxPublishers: maxPublishers) { | |
transform($0) | |
.map { value -> Result<T, Failure> in | |
Result.success(value) | |
} | |
.catch { | |
return Just<Result<T, Failure>>(Result.failure($0)) | |
} | |
} | |
.tryMap { result in | |
switch result { | |
case let .success(value): | |
return value | |
case let .failure(error): | |
throw error | |
} | |
} | |
.mapError { error in | |
error as! Failure | |
} | |
.eraseToAnyPublisher() | |
} | |
} | |
print("-----------------") | |
let subject2 = PassthroughSubject<Int, Error>() | |
let cancellable2 = subject2 | |
.print("before flatMap") | |
.flatMap2 { _ in | |
Fail<Int, Error>(error: MyError.error) | |
} | |
.print("after flatMap") | |
.sink { | |
print("completion: \($0)") | |
} receiveValue: { | |
print("receiveValue: \($0)") | |
} | |
print("Sending 1") | |
subject2.send(1) | |
print("Sending 2") | |
subject2.send(2) | |
print("Cancelling") | |
cancellable2.cancel() | |
print("Sending 3") | |
subject2.send(3) | |
/* | |
output: | |
after flatMap: receive subscription: (FlatMap) | |
after flatMap: request unlimited | |
before flatMap: receive subscription: (PassthroughSubject) | |
before flatMap: request unlimited | |
Sending 1 | |
before flatMap: receive value: (1) | |
after flatMap: receive error: (error) | |
completion: failure(__lldb_expr_13.MyError.error) | |
Sending 2 | |
before flatMap: receive value: (2) | |
Cancelling | |
Sending 3 | |
before flatMap: receive value: (3) | |
----------------- | |
after flatMap: receive subscription: (TryMap) | |
after flatMap: request unlimited | |
before flatMap: receive subscription: (PassthroughSubject) | |
before flatMap: request unlimited | |
Sending 1 | |
before flatMap: receive value: (1) | |
before flatMap: receive cancel | |
after flatMap: receive error: (error) | |
completion: failure(__lldb_expr_13.MyError.error) | |
Sending 2 | |
Cancelling | |
Sending 3 | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment