作者 | Shai Mishali
幾天前 RxSwift 5[1] 終於釋出了,這個版本在原始碼層面沒有太大的變動,更多的是捨棄了一些東西,同時重新命名了一些東西,另外也有一些底層的改進,讓我們來一起看看。
將 Relay 拆分成一個獨立的框架 -- RxRelay
Relay 是 Subject 上的一個很好的抽象層,可以讓您在不關心 errors 或 completion events 的情況下中繼元素。從它們被新增到 RxSwift 後,一直是作為 RxCocoa 工程的一部分而存在的。
一些開發人員對此並不滿意,因為這意味著必須匯入 RxCocoa 才能使用 Relay。 另外由於 Linux 下沒有 RxCocoa,所以在 Linux 環境下也無法使用 Relay。
由於上述原因,在 Swift 5 中將 Relays 獨立成 RxRelay [2],並調整了 RxSwift 的依賴圖,如下:


這讓您可以只使用 RxSwift 和 RxRelay,而不依賴於 RxCocoa(如果您不需要它),並且還與 RxJava 保持一致,在 RxJava 中,Relay 是一個單獨的框架。
注意:這是向後相容的更改,因為 RxCocoa 直接匯入了 RxRelay。意思是,您可以繼續匯入 RxCocoa 而無需匯入 RxRelay,一切都會像以前一樣工作。
棄用 TimeInterval,改用 DispatchTimeInterval
RxSwift 5 對 Schedulers 進行了重構,棄用了 TimeInterval,轉而使用 DispatchTimeInterval。當需要亞秒級時序時,DispatchTimeInterval 可以獲得更好的事件排程粒度和更高的穩定性。
這會影響所有基於時間的操作符,例如 throttle、timeout、delay、take 等。一個很有意思的副作用是,這消除了 take 的歧義。
RxSwift 4.x:

RxSwift 5.x:

Variable 最終被棄用
Variable 是早期新增到 RxSwift 中的一個概念,它允許您通過“設定”和“獲取”當前值來建立一個命令式的 bridge。這是一個看似有用的措施,可以讓開發人員更容易上手使用 RxSwift,直到他們完全適應“響應性思維”。
不過這種結構被證明是有問題的,因為開發人員嚴重濫用這種結構來建立高度命令式的系統,而不是使用 Rx 的宣告式性質。這對於響應式程式設計的初學者來說尤其常見,並且在概念上阻止了許多人理解這是一種不好的做法和程式碼味道。這就是為什麼在 RxSwift 4.x 中已經使用執行時警告來告知將棄用 Variable 的原因。
在 RxSwift 5 中,它現在已被正式完全棄用,如果您需要這種行為,建議的方法是使用 BehaviorRelay(或 BehaviorSubject)。
RxSwift 4.x:

RxSwift 5.x:

新增 do(on:) 過載
do 是一個很棒的操作符,當你想要執行某些副作用(如日誌記錄)或只是“監聽”流的中間過程。
為了與 RxJava 保持一致,RxSwift 現在不僅提供 do(onNext:),還提供如 do(afterNext:) 這樣的過載。onNext 表示元素髮出的時刻,而 afterNext 表示發出並向下遊推送的時刻。
RxSwift 4.x:

RxSwift 5.x:

bind(to:) 現在支援多個觀察者
在某些情況下,您必須將流繫結到多個觀察者。在 RxSwift 4 中,您通常只是複製繫結程式碼:

RxSwift 5 現在支援繫結到多個觀察者:

這仍然解析到單個 Disposable,這意味著它向後相容單觀察者變體。
一個新的 compactMap 操作符
作為開發人員,您可能經常處理 Optional 值的流。為了解包這些值,社群已經有了自己的解決方案,例如來自 RxSwiftExt 的解包運算子或來自 RxOptional 的 filterNil。
RxSwift 5 新增了一個新的 compactMap 操作符,以與 Swift 標準庫保持一致,將此功能引入核心庫。
RxSwift 4.x:

RxSwift 5.x:

toArray() 現在返回 Single
toArray() 是一個操作符,它在流完成後將整個流作為陣列發出。
一直以來這個操作符總是返回一個 Observable,但是由於 Traits 的引入 - 特別是 Single,將返回型別更改為 Single 以提供該型別的安全性和僅保證從此操作符獲取單個發射值是很有意義的。
RxSwift 4.x:

RxSwift 5.x:

泛型約束命名整理
RxSwift 是泛型約束的重度使用者。從早期開始,庫就使用單字母約束來描述某些型別。 例如,ObservableType.E 表示 Observable 流的泛型型別。
這樣可以正常工作,但會引起一些混淆,例如 O 可以代表不同場景中的 Observable 和 Observer,或 S 可以代表 Subject 和 Sequence.
此外,這些單字母約束並沒有提供良好的自我描述,並使非程式碼貢獻者很難理解文件。
出於這些原因,我們對私有和公共介面的大多數泛型約束進行了大修,使其具有更多資訊以便理解。
The most widely impacting rename is E and ElementType to simply Element.
影響最大的重新命名將 E 和 ElementType 改為 Element。
RxSwift 4.x:

RxSwift 5.x:

泛型重新命名非常廣泛。下面是一個大致完整的列表。這些更改中的大多數都與 RxSwift 的內部 API 有關,其中只有少數會影響到開發人員:
- E 和 ElementType 重新命名為 Element;
- TraitType 重新命名為 Trait;
- SharedSequence.S 重新命名為 SharedSequence.SharingStrategy;
- 依情況 O 被重新命名為 Observer 和 Source;
- C 和 S 分別重新命名為 Collection 和 Sequence;
- 依情況 S 也被重新命名為 Subject;
- R 被重新命名為 Result;
- ReactiveCompatible.CompatibleType 重新命名為ReactiveCompatible.ReactiveBase。
社群專案
許多 RxSwift 社群專案已經遷移到 RxSwift 5 併發布了相應的版本,因此遷移過程應該相對順利。已遷移的一些專案包括:RxSwiftExt,RxDataSources,RxAlamofire,RxOptional 等。
總結
上面列出的更改是開發人員會遇到的主要更改,但是還有更多小的修補程式超出我們帖子的範圍,例如在 Linux 下完全修復與 Swift 5 的相容性、輕微異常等。
請隨時檢視完整的更改日誌並參與官方儲存庫中的討論:github.com/ReactiveX/R…
參考
關注我們
歡迎關注我們的公眾號:zsxjtip,也歡迎加入我們的群組討論問題。可以加微信 coldlight_hh
/wsy9871
進入我們的 iOS
/flutter
微信群。
