Composing streams, and where the thread goes
Operators are publishers that wrap other publishers. map returns a Publishers.Map, which holds
its upstream and transforms each value as it passes. Nothing runs until something subscribes.
let results = searchTerms
.removeDuplicates()
.flatMap { term in
api.search(term)
.catch { _ in Just([]) }
}
.receive(on: DispatchQueue.main)
Three things worth knowing about this chain:
flatMap keeps every inner publisher alive until it completes. For search-as-you-type that
means overlapping requests and out-of-order results; switchToLatest cancels the previous one.catch ends the stream it recovers. Once an error passes through, that upstream is finished —
which is why the recovery is placed inside flatMap, on the inner publisher, not outside it.receive(on:) moves delivery, not work. Whatever api.search does happens where it already
happened; only the values after this point arrive on main.This is a template chapter. The full text is still being written.