Home

Operators

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.