Trang chủ

Toán tử

Ghép luồng dữ liệu, và luồng thực thi chạy đi đâu

Toán tử là những publisher bọc quanh publisher khác. map trả về một Publishers.Map, giữ lấy nguồn phía trên và biến đổi từng giá trị đi qua. Chưa có gì chạy cho tới khi có ai đó đăng ký.

let results = searchTerms
    .removeDuplicates()
    .flatMap { term in
        api.search(term)
            .catch { _ in Just([]) }
    }
    .receive(on: DispatchQueue.main)

Ba điều đáng biết về chuỗi này:

  • flatMap giữ mọi publisher con sống cho tới khi chúng kết thúc. Với tìm kiếm gõ tới đâu tra tới đó, điều đó nghĩa là các request chồng lên nhau và kết quả về sai thứ tự; switchToLatest sẽ huỷ cái trước đó.
  • catch kết thúc luồng mà nó cứu. Một khi lỗi đi qua, nguồn phía trên coi như xong — nên phép cứu lỗi được đặt bên trong flatMap, trên publisher con, chứ không phải bên ngoài.
  • receive(on:) chuyển nơi giao giá trị, không chuyển nơi làm việc. api.search làm gì thì vẫn làm ở chỗ cũ; chỉ những giá trị đi qua điểm này mới về luồng chính.

Vì sao các chương được nhóm như thế này

Combine có khoảng một trăm toán tử và một chuyến dạo qua chúng theo thứ tự bảng chữ cái thì vô dụng. Ở đây chúng được nhóm theo câu hỏi mà chúng trả lời, vì trong thực tế bạn biết mình muốn gì và chỉ cần cái tên.

Biến đổi — một luồng vào, một luồng ra, giá trị bị thay đổi trên đường đi. map, compactMap, scan, flatMap, switchToLatest, và khác biệt giữa hai cái cuối, lựa chọn có hệ quả lớn nhất trong cuốn sách này.

Kết hợp — nhiều luồng vào, một luồng ra. merge, combineLatest, zip, và những toán tử chỉ lấy giá trị đầu tiên. Chọn sai ở đây sinh ra một màn hình cập nhật quá thường xuyên hoặc một màn hình không bao giờ cập nhật, và cả ba hành xử rất khác nhau ngay khi một nguồn chậm hơn những nguồn còn lại.

Thời gian — debounce, throttle, delay, timeout, collect(.byTime:), và measureInterval. Mọi thứ ở đây đều cần một scheduler, và việc chọn scheduler nào sẽ đổi cả hành vi.

Lỗi — catch, retry, replaceError, mapError, setFailureType, và kỷ luật quyết định ở đâu trong một chuỗi thì một lỗi được phép là chí mạng.

Quy tắc nằm dưới tất cả

Một lỗi kết liễu cái luồng mà nó chạm tới. Không phải giá trị — mà là cả luồng. Một khi một lỗi đi qua một điểm trong chuỗi, mọi thứ nằm dưới điểm đó nhận một tín hiệu kết thúc và subscription chấm dứt. Không giá trị nào sau đó đến được nữa, vì chẳng còn gì để mà đến.

Đây là câu quan trọng nhất về các toán tử Combine, và nó chi phối vị trí đặt gần như mọi toán tử xử lý lỗi bạn sẽ viết. Một catch ở cuối pipeline cứu được một lần rồi pipeline chết; đúng cái catch ấy đặt bên trong một flatMap thì cứu publisher con và để luồng ngoài sống tiếp để xử lý giá trị kế tiếp.

Gần như mọi lỗi kiểu “lần đầu chạy được rồi sau đó tịt” trong Combine đều là sự phân biệt đó.