Swift — Convenience Publishers

讓我們來看如何使用 Combine 中的 Convenience Publishers

Jeremy Xue
Jeremy Xue ‘s Blog
6 min readSep 6, 2020

--

✒︎ 前言:

在之前介紹 Combine Publisher 裡面有提到關於 Convenience Publisher 的內容,而今天我們就來簡單介紹它的概念以及使用方式。若還沒看過之前 Convenience Publisher 也歡迎參考以下文章:

✒︎ Convenience Publishers

⒈ Just

一個發布者。只會向每個訂閱者發出一次值,然後結束。

你可以使用 Just 發布者來啟動發布者鏈。當使用 Publishers.Catch 替換值時,Just 發布者也很有用。

Result.Publisher 相比,Just 發布者不會因為錯誤而失敗。與 Optional.Publisher 不同,Just 發布者總是產生一個值。

我們可以透過任何值來初始化 Just,並且透過 sink 等方式連接。我們可以透過 console 看到 Just 在傳遞一次輸出值之後,立即結束。

⒉ Empty

一個從不發布任何值的發布者,可以選擇立即完成。

你可以使用 Empty(completeImmediately: false) 創建一個 “Never” 的發布者,一個從不發送值,從不完成或失敗的發布者。

如果你像如同官方文件中提到的,創建一個不發送值,也不會完成或失敗的發布則,則可以在 Empty 初始化時將 completeImmediately 設為 false。這時你的 console 應該不會出現任何東西。

如果想要傳遞立即完成的話只需要將 completeImmediately 設為 true 即可,也可以選擇不寫(默認為 true):

在你需要返回一個發布者時,但又不想傳遞任何值或者是完成/錯誤時很有用(或是有錯誤不想進行任何動作)。

⒊ Fail

立即以指定的錯誤終止的發布者。

這邊 Fail 就是一個發送錯誤的發布者,我們可以透過一個 Error 的內容來初始化它,接著 Fail 會將 Error 這個發布給所有訂閱對象,並且終止。

⒋ Record

允許紀錄一系列輸入和完成內容的發布者,用於之後向每個用戶回放。

透過 Record 我們可以創建一個預先記錄的發布者,並且用於之後回放。也可以在傳遞一序列的值後發布正常成功或是失敗。

而我們也可以用另一種方式使用它:

Record 也可以使用其他 Record 中的 recording 來初始化:

⒌ Future

最終產生單個值,然後完成或失敗的發布者。

Future 可以結合使用任何異步調用,並使用該調用來生成值或完成。 當要發出單個請求或獲得單個響應(使用的 API 具有完成處理程序閉包)時,它是一個好的選擇。

雖然我們已經有 URLSession.shared.dataTaskPublisher 可以創建發布者了,但還是一樣使用 URLSession 來做個 Future 的範例:

⒍ Deferred

在提供閉包為新的訂閱者創建發布者之前,等待訂閱的發布者。

通常會看到 DeferredFuture 兩個發布者一起使用,我們可以透過一個 Deferred 來包裝 Future 。在請求訂閱之前,Deferred 推遲設置任何發布者數據結構,這提供了將發布者的設置推遲到實際需要之前的方法。

我們可以簡單從一個 retry 的範例來看使用 Deferred 的差別。首先我們使用 Future 來創建一個發布者,Future 會在 3秒後執行 promise(.failure) ,而我們會希望這個發布者再發生錯誤時,重新嘗試 3 次,直到正確的獲取數據。

而我們使用 Future 的狀況下,當我們發生錯誤時,並沒有進行重試,而是立即錯誤終止。如果我們想要依照我們的方式進行重試(成功或是三次失敗)時,我們可以使用 Deferred 發布者包裝我們的 Future

這時候你可以看到在每次失敗後,我們會再一次的執行 Future 中的內容,並且在錯誤發生時進行重試的動作,直到成功或是失敗三次後,會在獲取成功或是失敗相關的內容。

--

--

Jeremy Xue
Jeremy Xue ‘s Blog

Hi, I’m Jeremy. [好想工作室 — iOS Developer]