If I send to PassthroughSubject<Void, Error>
, this process will run once, but if I send it more than once, the process in the flatMap will not run. Why is this?
var testTappedSubject = PassthroughSubject<Void, Error>()
testTappedSubject
.print("testTappedSubject")
.flatMap({ () -> AnyPublisher<Int, Error> in
print("called test")
return Fail(error: LoginError.someError(error: .unknown))
.eraseToAnyPublisher()
})
.sink { error in
print("error", error)
} receiveValue: { value in
print("pressed", value)
}
.store(in: &cancellables)
That's the way Combine (and other Reactive frameworks) work.
you are setting up a subscription to a publisher, and the only thing that subscription does is emit an error:
return Fail(error: LoginError.someError(error: .unknown))
.eraseToAnyPublisher()
When a publisher emits an error. the subscription completes and does not receive any more events.
I put a version of your code in a playground:
import Combine
var cancellables = Set<AnyCancellable>()
var testTappedSubject = PassthroughSubject<Void, Error>()
enum LoginError: Error {
case unknown
}
testTappedSubject
.print("testTappedSubject")
.flatMap({ () -> AnyPublisher<Int, Error> in
print("called test")
return Fail(error: LoginError.unknown)
.eraseToAnyPublisher()
})
.sink { error in
print("error", error)
} receiveValue: { value in
print("pressed", value)
}
.store(in: &cancellables)
testTappedSubject.send()
testTappedSubject.send()
testTappedSubject.send()
and the results in the console were:
testTappedSubject: receive subscription: (PassthroughSubject)
testTappedSubject: request unlimited
testTappedSubject: receive value: (())
called test
error failure(__lldb_expr_72.LoginError.unknown)
testTappedSubject: receive value: (())
testTappedSubject: receive value: (())
This shows that an unlimited subscription was received, and then, after sending a value, your print("called test")
is called and then an error is received.
The subscription is now complete.
Sending more values just shows that a value was received, but nothing was sent to the subscriber.