RxSwift之traits前篇:RxSwift traits

注意!以下可能是計算機英語業(yè)余水平coder翻譯,歡迎品鑒,如有不當,留言改刪!謝謝。
原文在這里:Traits (formerly Units)

Traits (formerly Units)


這篇文章將要試圖描述traits是什么,為什么它是個有用的概念以及怎樣構造和運用它。

總則


為什么

Swift強大的類型系統(tǒng)能夠用來提升程序的正確性和穩(wěn)定性,并且使得使用Rx更加簡潔和直觀。

和原始的Observable相比,Traits有助于跨接口邊界溝通和確??捎^察序列屬性,而且提供上下文含義、語法糖,目標是更具體的用例,而Observable則能夠用于任何的上下文環(huán)境。因此,Traits是完全可選的,你可以在你程序的任何地方自由使用原始的Observable序列,因為所有的RxSwift/RxCocoa核心APIs都支持它們。

注意:這篇文章里的一些Traits是專門針對RxCocoa工程的(例如Driver),還有一些是整個RxSwift項目的一部分,然而,同樣的原則可以容易地在其他的Rx實踐里實現。并不需要使用私有API魔法。

它們怎么工作

Traits僅僅是一個封裝的結構體,它具有一個單獨的只讀Observable序列屬性。

struct Single<Element> {
    let source: Observable<Element>
}

struct Driver<Element> {
    let source: Observable<Element>
}
...```
你可以把它們想成是一種針對Observable的建造者模式的實現,當一個Trait被構建出來后,調用`.asObservable()`將會把它轉化回普通的可觀察序列。

####RxSwift traits
***
#####Single
Single是Observable的一種變體,總是能夠保證只發(fā)送一個元素或者錯誤,而不是發(fā)送一系列元素。
* 只發(fā)送一個元素或者錯誤
* 不共享副作用

使用Single的一個常見的用例是執(zhí)行只能返回一個響應或者一個錯誤的HTTP請求,但是如果你只關心一個單一的元素,而不是一個無限的元素流,一個Single就可以模擬任何用例。
######創(chuàng)建一個Single
創(chuàng)建一個Single和創(chuàng)建一個Observable很相似,下面是一個簡單的例子:

func getRepo(_ repo: String) -> Single<[String: Any]> {
return Single<[String: Any]>.create { single in
let task = URLSession.shared.dataTask(with: URL(string: "https://api.github.com/repos/(repo)")!) { data, _, error in
if let error = error {
single(.error(error))
return
}

        guard let data = data,
              let json = try? JSONSerialization.jsonObject(with: data, options: .mutableLeaves),
              let result = json as? [String: Any] else {
            single(.error(DataError.cantParseJSON))
            return
        }

        single(.success(result))
    }

    task.resume()

    return Disposables.create { task.cancel() }
}

}```
然后你可以按照以下方式使用它:

getRepo("ReactiveX/RxSwift")
    .subscribe { event in
        switch event {
            case .success(let json):
                print("JSON: ", json)
            case .error(let error):
                print("Error: ", error)
        }
    }
    .disposed(by: disposeBag)

或者按照如下方式使用subscribe(onSuccess:onError:)

getRepo("ReactiveX/RxSwift")
    .subscribe(onSuccess: { json in
                   print("JSON: ", json)
               },
               onError: { error in
                   print("Error: ", error)
               })
    .disposed(by: disposeBag)```
上面的訂閱提供了一個`SingleEvent`枚舉,可以是`.success`包含了該Single類型的一個元素,或者是`.error`。除了第一個,沒有其他的事件會被發(fā)送。
在一個原始的Observable序列上使用`.asSingle()`從而把它轉化為一個Single也是有可能的。
#####Completable
Completable是Observable的一種變體,它只能完成或者是發(fā)送一個錯誤。它能夠保證不發(fā)送任何元素。
* 不發(fā)送元素
* 發(fā)送一個完成事件,或者是一個錯誤
* 不分享副作用

關于Completable的一個有用的用例是:當我們只關心一個操作已經完成了這個事實,而不關心那個操作完成后生成的元素時,可以用Completable來做模板。你可以拿Completable和`Observable<void>`(Observable<void>不能發(fā)送元素)作比較。
######創(chuàng)建一個Completable
創(chuàng)建一個Completable和傳建一個Observable相似,下面是一個簡單的例子:

func cacheLocally() -> Completable {
return Completable.create { completable in
// Store some data locally
...
...

   guard success else {
       completable(.error(CacheError.failedCaching))
       return Disposables.create {}
   }

   completable(.completed)
   return Disposables.create {}
}

}```
然后你可以像下面這樣使用它:

cacheLocally()
    .subscribe { completable in
        switch completable {
            case .completed:
                print("Completed with no error")
            case .error(let error):
                print("Completed with an error: \(error.localizedDescription)")
        }
    }
    .disposed(by: disposeBag)```
或者像下面這樣利用`subscribe(onCompleted:onError:) `:

cacheLocally()
.subscribe(onCompleted: {
print("Completed with no error")
},
onError: { error in
print("Completed with an error: (error.localizedDescription)")
})
.disposed(by: disposeBag)```
上面的訂閱提供了一個CompletableEvent枚舉,該枚舉有兩個成員:.completed(表明操作沒有錯誤地完成了)和.error。除了第一個事件,其他事件不會再被發(fā)送。

Maybe

Maybe是恰好處于Single和Completable之間的一種Observable變體。它可以只發(fā)送一個元素,也可以不發(fā)送任何元素而完成,或者發(fā)送一個錯誤。
注意:這三種事件中的任何一個都會終止Maybe,也就是說,一個有完成事件的Maybe不能再發(fā)送一個元素,一個發(fā)送了一個元素的Maybe不能再發(fā)送一個完成事件。*

  • 發(fā)送一個完成事件,或者一個單一的元素,或者一個錯誤
  • 不分享副作用

任何可能發(fā)送一個元素,但不是必須要發(fā)送一個元素的操作都可以用Maybe來做模型。

創(chuàng)建一個Maybe

創(chuàng)建一個Maybe和創(chuàng)建一個Observable類似,下面是一個簡單的例子:

func generateString() -> Maybe<String> {
    return Maybe<String>.create { maybe in
        maybe(.success("RxSwift"))

        // OR

        maybe(.completed)

        // OR

        maybe(.error(error))

        return Disposables.create {}
    }
}```
然后你可以像下面這樣去使用它:

generateString()
.subscribe { maybe in
switch maybe {
case .success(let element):
print("Completed with element (element)")
case .completed:
print("Completed with no element")
case .error(let error):
print("Completed with an error (error.localizedDescription)")
}
}
.disposed(by: disposeBag)```
或者像下面這樣利用subscribe(onSuccess:onError:onCompleted:)來實現:

generateString()
    .subscribe(onSuccess: { element in
                   print("Completed with element \(element)")
               },
               onError: { error in
                   print("Completed with an error \(error.localizedDescription)")
               },
               onCompleted: {
                   print("Completed with no element")
               })
    .disposed(by: disposeBag)```
在一個原始的Observable序列上使用`.asMaybe()`可以轉化為一個Maybe。
最后放上整篇翻譯的后半部分:[RxSwift之traits后篇:RxCocoa traits](http://www.itdecent.cn/p/8e503672588a)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現,斷路器,智...
    卡卡羅2017閱讀 136,596評論 19 139
  • 最近在學習RxSwift相關的內容,在這里記錄一些基本的知識點,以便今后查閱。 Observable 在RxSwi...
    L_Zephyr閱讀 1,897評論 1 4
  • 1.RxSwift初識 RxSwift是 ReactiveX 的swift版本,是一種函數式響應編程的框架。RxS...
    MrMessy閱讀 3,273評論 0 11
  • 小縣城的夜晚隨著夏季的來臨開始逐漸變的沸騰起來,道路上車水馬龍。 那晚文與我就站在這縣城最熱鬧的街道邊,舉著招生的...
    L源源閱讀 655評論 1 8
  • 今天有朋友問我,是不是和愛人關系不好,我笑了。 其實只是內心有莫名的孤獨罷了!
    云之絮語閱讀 211評論 0 0

友情鏈接更多精彩內容