RxSwiftでsubscribeをネストされると困る
はじめに
RxSwiftでsubscribe
をネストされると困るという話を最小限のコードで説明してみる。
例えば次のようなコードがあるとする、これはやってることはシンプルだがこのような書き方を普段しているようなら、処理が複雑になっていくにしたがって読みづらいコードになる。
textField.rx.text
.subscribe(onNext: { text in
GitHubRepo.search(from: text).subscribe(onNext: { result in
...
})
.disposed(by: disposeBag)
})
.disposed(by: disposeBag)
このコードをもう少しシンプルに再現しやすいサンプルでネストしないようにしてみる。
シンプルなネストの例とその解決案
Swift.Sequence
な1, 2, 3を文字列と結合する例を考えてみる。
Observable.of(1, 2, 3)
.subscribe(onNext: {
let observable = Observable.of("\($0)A", "\($0)B", "\($0)C")
observable.subscribe(onNext: {
print($0)
})
})
出力は次の通り
1A
2A
3A
これを解決するため、ネストさせたくなったらまずはflatMap
系を思い出してほしい。これも出力は同じになる。
Observable.of(1, 2, 3)
.flatMap {
Observable.just("\($0)A")
}
.subscribe(onNext: {
print($0)
})
しかし、この例がそもそもシンプルすぎるからこんな簡単に置き換えられるわけだ。「1つのシーケンスをまた違う1つのシーケンスにしたいからflatMap
で置き換えられているだけじゃないか」と思ったかもしれない。そのため例をもう少しだけ複雑にしてみる。
ほんの少し複雑なネストの例とその解決案
subscribe
でログ出力を行わないといけないことを考えた例にしてみる。
Observable.of(1, 2, 3)
.subscribe(onNext: {
Logger.log("log1:\($0)")
let observable = Observable.just("\($0)A")
observable.subscribe(onNext: {
Logger.log("log2:\($0)")
print($0)
})
})
// Loggerは適当に...こんなニュアンスだとしてやってください
struct Logger {
static func log(_ message: String) {
print(message)
}
}
このような場合はdo
オペレータを使って副作用を分けてほしい
Observable.of(1, 2, 3)
.do(onNext: {
Logger.log("log1:\($0)")
})
.flatMap {
Observable.just("\($0)A")
}
.do(onNext: {
Logger.log("log2:\($0)")
})
.subscribe(onNext: {
print($0)
})
もちろんシーケンスを分岐して別々に処理を書いてもいい。この例ではわざわざ分岐する必要性はないが一応例を示す。
let observable = Observable.of(1, 2, 3)
observable
.do(onNext: {
Logger.log("log1:\($0)")
})
observable
.flatMap {
Observable.just("\($0)A")
}
.do(onNext: {
Logger.log("log2:\($0)")
})
.subscribe(onNext: {
print($0)
})
分岐をする必要性はないが、アイデアの一つとして知っておくと良いと思う。
とにかくシーケンスの副作用の実行をまとめて一箇所のsubscribe
でやろうとするからコードが読みづらくなってしまうので、それを避けるために考えを巡らせたい。
おわりに
上記の例はCold Observableを使ってとてもシンプルな例としたが、実際のアプリ開発ではこのようなシンプルなコードではないためコードの処理を追いづらい。他にはSubject
やRelay
に値をonNext
していたりしてキツイ。一つのシーケンスの処理を追っていたら複数イベントが発火し、それがそこだけの問題なのか判断ができないままコードを追いかけないといけない。
そういうときにこそオペレータを駆使したりRxを調べたりして宣言的にコードを書くことを思い出してほしい。じゃないとRxを使ってるだけの読みづらいコードになってしまうわけですよね。
Author And Source
この問題について(RxSwiftでsubscribeをネストされると困る), 我々は、より多くの情報をここで見つけました https://qiita.com/yimajo/items/393ec9b3b445ec170ce4著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .