jdmoreira
(João D. Moreira)
1
I'm experiencing some behaviour that I did not expect.
For example
let cancellable = [1, 2, 3]
.publisher
.flatMap { _ -> Empty<Void, Never> in
print("Entered")
return Empty(completeImmediately: true)
}.print("DEBUG").sink(receiveValue: { })
which prints
DEBUG: receive subscription: (FlatMap)
DEBUG: request unlimited
Entered
Entered
Entered
DEBUG: receive finished
but I would expect it to only print Entered once. I would expect it to finish immediately after the flatMap.
Similarly
let subject: PassthroughSubject<Void, Never> = PassthroughSubject()
let cancellable = subject
.flatMap { _ -> Empty<Void, Never> in
print("Entered")
return Empty(completeImmediately: true)
}.print("DEBUG").sink(receiveValue: { })
subject.send(())
prints
DEBUG: receive subscription: (FlatMap)
DEBUG: request unlimited
Entered
It never finishes!
I would expect it to finish.
The same behaviour also happens with map { ... }.switchToLatest() which is even stranger in my opinion.
Can someone help me understand what's happening and why?
When your flatMapped publisher completes it does not complete the upstream publisher since the upstream publisher might still have values to emit.
Consider the following example:
[1, 2, 3].publisher
.flatMap { int in
let url = URL(string: "https://somepage.com/page/\(int)")!
return URLSession.shared.dataTaskPublisher(for: url)
}
If flatMap would work like you expect it to, your pipeline might perform one network call, or it might perform three because there's no way of knowing when the first data task completes since it's run asynchronously.
That immediately demonstrates why ending the upstream publisher when the flat mapped publisher completes would be problematic.
jdmoreira
(João D. Moreira)
3
Thanks for your explanation. I see your point.
Errors will still escape the flatMap so I have some trouble understanding why it would be different, the same logic applies. It would make sense that neither of them escape the flatMap or both of them escape.
I believe on RxSwift both .complete and .error(..) escape flatMaps