Hydra 是一個 Swift 3 編寫的異步框架, 它輕量級并且支持幾乎所有的異步方法 like always
, validate
, timeout
, retry
, all
, any
, pass
, recover
, map
, zip
, defer
and retry
等等
其實, 在我們已經(jīng)習(xí)慣了 RXSwift 或者 ReacativeCocoa 的時候, 我們也許永遠(yuǎn)也用不到 Hydra, 但是剛才說的兩個函數(shù)響應(yīng)式的類庫不僅僅是包含了異步的功能, 其實更確切的說異步只是響應(yīng)式的一種表現(xiàn)形式, 我個人是非常希望通過一個庫來好好學(xué)習(xí)一下底層異步的實現(xiàn)以及封裝, 所以, 我選擇了 Hydra
兩個概念
第一個核心概念就是 Promise, 我最早知道這個概念是通過 JS, 他能很好的實現(xiàn)連續(xù)的異步調(diào)用, 消除了被我們稱之為 "回調(diào)地獄" 的代碼風(fēng)格, 讓我們更加優(yōu)雅的把注意力集中到業(yè)務(wù)本身, Hydra 其實就是 Promise 的 Swift 版本而已, 關(guān)于 Promise 的細(xì)節(jié), 網(wǎng)上一搜一大堆, 我就不在贅述了.
第二個核心概念就是 GCD, 做 iOS 或者 Mac 開發(fā)不知道 GCD 簡直就是個笑話, Hydra 的底層就是使用 GCD 實現(xiàn)的, 更多細(xì)節(jié)問題, 我會在之后的代碼中向大家一一說明.
從原理說起
Promise 在我的理解中其實就是狀態(tài)的傳遞, 如果拋除未運(yùn)行的話, 無非 成功
or 失敗
兩種, Promise 的連續(xù)調(diào)用無非就是捕獲當(dāng)前的狀態(tài), 并生成新的狀態(tài), 之后向下傳遞.
internal enum State<Value> {
case pending
case resolved(_: Value)
case rejected(_: Error)
...
}
那么有了狀態(tài), 配套的就要有人去監(jiān)聽狀態(tài)的變化, 這里封裝了 Observe 來監(jiān)聽, 當(dāng) Observe 發(fā)生了變化或者 State 發(fā)生了變化的時候, 都會調(diào)用相應(yīng)的 Observe 的方法
internal enum Observer<Value> {
typealias ResolveObserver = ((Value) -> (Void))
typealias RejectObserver = ((Error) -> (Void))
case onResolve(_: Context, _: ResolveObserver)
case onReject(_: Context, _: RejectObserver)
...
}
Promise 的方法及其實現(xiàn)方式
一個基本的概念就是, 下面的方法基本都會返回一個新的 promise, 而新的 promise 的 resolve 和 reject 是被包裝成為 Observer 被添加到老 promise 中, 當(dāng)老 promise 任務(wù)結(jié)束, 觸發(fā)對應(yīng)的 observer
All
概念就是監(jiān)聽多個異步 Promise, 全部成功調(diào)用 resolve, 出現(xiàn)錯誤調(diào)用 reject
實現(xiàn)方式是使用一個值記錄未完成的任務(wù), 當(dāng)未完成的任務(wù)為 0 的時候, 結(jié)束任務(wù), 感覺與 GCD Group 類似, 區(qū)別就是如果發(fā)生任何的錯誤, 立刻停止所有調(diào)用
Always
always 就是無論任務(wù)成功還是失敗都會調(diào)用 always 的方法
實現(xiàn)方式是 把 resolve 和 reject 都包裝成為 Observer, 并且在 Observer 的執(zhí)行方法中均執(zhí)行 always 的 body
Any
Any 的含義就是讓多個 promise 監(jiān)聽一個 promise, 實現(xiàn)方式也很簡單, 就是把所有的監(jiān)聽 promise 全部作為 observer 添加到 目標(biāo) Promise 中
Catch
catch 作為 promise 最基礎(chǔ)的用法之一, 就是為了截獲錯誤, 當(dāng)之前的 promise 出現(xiàn) error 的時候, 觸發(fā) catch promise 的 observer 對象, 執(zhí)行 catch 的 body 函數(shù)
Defer
這個其實是配合 then 使用的, 在 then 的 body 被調(diào)用的時候, 使用 queue.asyncAfter 延后執(zhí)行
Map
map 分為兩種形式, 第一種為并列方式, 其實與 all 相同, 第二種為 連續(xù)方式 其實內(nèi)部實現(xiàn)就是 使用 reduce 函數(shù), 連續(xù)使用調(diào)用 then 函數(shù)監(jiān)聽前面的 promise
Pass
這個就沒什么可說的了, 就是無論前面?zhèn)骰貋硎裁? 直接進(jìn)行下面的 promise
Recover
當(dāng)前面發(fā)生錯誤的時候, 可以在這里嘗試處理錯誤, 內(nèi)部實現(xiàn)是 連續(xù)使用了 then 和 catch 并且在 catch 中 調(diào)用 Recover body
Reduce
與 map 的 連續(xù)類型相同, 內(nèi)部使用了 reduce 函數(shù)連續(xù) then 前面一個 promise
Then
then 是 promise 的最常用也是最基礎(chǔ)的方法了, 就是接收上一個, 實現(xiàn)方式也是最基本的 給 舊的 promise 添加 observer
Retry
執(zhí)行 promise, 當(dāng)失敗的時候重新執(zhí)行 任務(wù), 內(nèi)部的實現(xiàn)原理是 在 reject 的 observer 的執(zhí)行方法中, 去判斷是否需要 retry, 如果需要的話, 重新執(zhí)行 promise, 知道成功 或者重試次數(shù)到達(dá)上線
Timeout
超時調(diào)用, 即是在任務(wù)如果超時了, 直接返回超時 error, 實現(xiàn)方式是在執(zhí)行任務(wù)的同時添加一個 gcd after 方法, 如果這個方法被調(diào)用了, 直接返回 錯誤
Validate
對返回的結(jié)果進(jìn)行驗證, 實現(xiàn)方式是在 promise then 方法中進(jìn)行 Validate
Zip
這個是把多個 promise 同時執(zhí)行, 并且把返回結(jié)果打包成為元祖返回, 內(nèi)部使用的是 promise all 方法
寫在最后
我們在使用異步框架的時候, 往往只使用其中最基礎(chǔ)的功能, 一些高級功能我們并不會使用甚至根本都不知道是什么意思, 在這里, 我對 Hydra 的一些方法進(jìn)行了簡單描述, 這些方法名基本都是通用的, 下次你再看到這些名字的時候, 我希望你知道它是干什么的, 并且勇敢的使用它們