Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Rx入門
ponday
November 21, 2017
Technology
1
1.1k
Rx入門
Rx勉強会@福岡 #0 発表資料
学習コストは高いけど使いこなせると強力だよっていうことを言いたかった。
ponday
November 21, 2017
Tweet
Share
More Decks by ponday
See All by ponday
関数型でGoFのデザインパターンやってみる
honda
0
450
TypeScriptの型表現
honda
10
2.6k
Web Componentsの今
honda
1
320
これまでのReact、これからのReact
honda
0
190
Gatsbyお試し
honda
0
83
styled-components or emotion?
honda
0
540
Web ComponentsとAngular
honda
0
87
Atomic Design周りについての私見
honda
1
410
え、まだWeb Componentsを未来の技術だと思ってるの?
honda
2
560
Other Decks in Technology
See All in Technology
〇〇みたいな検索作ってと言われたときに考えること / thinking before developing search system like that one
ryook
5
2.7k
ECS Fargate+Mackerelにおける監視費用を削減するまでの話
nulabinc
PRO
1
490
CityGMLとFBXの連携で地理空間のエンタメ化
soh_mitian
0
750
品質特性のすすめ
honamin09
0
180
私のAWS愛を聞け! ~ここが好きだよStep Functions~ #devio2022
kongmingstrap
0
290
ログ集約基盤をCloudWatchからOpenSearchに変えてみた
yuhta28
0
140
AWSを使う上で意識しておきたい、クラウドセキュリティ超入門(駆け足版)
kkmory
0
220
Step-by-Step MLOps and Microsoft Products
shisyu_gaku
2
590
聊聊 Cgo 的二三事
david74chou
0
330
cobra は便利になっている
nwiizo
0
140
SBOMを利用したソフトウェアサプライチェーンの保護
masahiro331
1
200
DevelopersIO 2022 俺のTerraform Pipeline
takakuni
0
440
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
261
37k
Producing Creativity
orderedlist
PRO
334
37k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
119
28k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
6
580
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
212
20k
It's Worth the Effort
3n
172
26k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
223
49k
Infographics Made Easy
chrislema
233
17k
Building an army of robots
kneath
299
40k
Automating Front-end Workflow
addyosmani
1351
200k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
62k
How New CSS Is Changing Everything About Graphic Design on the Web
jensimmons
213
11k
Transcript
Rx入門 Rx勉強会@福岡 #0 / Nov 21, 2017 ponday (@ponday_dev)
Profile Honda, Yusuke (@ponday_dev) Community - chibi-developer - ng-fukuoka Like
- JavaScript / TypeScript / Kotlin - RxJS / Angular / Vue.js Other skills - C# / Java / Python - Spring Boot SIer / System Engineer
ご注意
ご注意 - サンプルコードはRxJS 5.5で記載しています - 他言語利用者の方、すみません。 - 他言語のライブラリとの互換性の観点から、Lettable Operatorsは使用してい ません。
- 予約語などの兼ね合いから、他の言語と関数名が一致していない場合があり ます。 - 極力コードは解説しますが、漏れや分かりにくい点があれば 遠慮なく聞いてください
Rxとは?
Rxとは - ReactiveX / Reactive Extensionsのこと - 関数型リアクティブプログラミング向けのライブラリ - FRP
/ Functional Reactive Programmingとも - 厳密にはFRPではない、という批判も一部業界からあるようなので非同期処理 向けのライブラリ、と思っておけば良い - MicrosoftがC#向けに開発した『Rx.NET』が元 - NetflixがJavaへの移植版である『RxJava』をリリースしたことによ り注目度が高まる - アプリ、WebのUI部分での利用が多い (RxJS, RxSwift, RxJava...)
Rxファミリー - Rx.NET (C#) - RxJava (Java) - RxSwift (Swift)
- RxJS (JavaScript) - RxKotlin (Kotlin) - UniRx (Unity C#) - RxScala (Scala) - RxClojure (Clojure) - RxCpp (C++) - Rx.rb (Ruby) - RxPY (Python) - RxGo (Go) - RxGroovy (Groovy) - RxJRuby (JRuby) - RxPHP (PHP) - reactive (Elixir) - RxDart (Dart)
Observerパターン - GoFで提唱されたデザインパターンの一つ - Pub/Subパターンとも - Rxの根底にある考え方 - 以下のような場合に有効 -
イベントドリブンなプログラム - 状態の変化に応じて処理が発生するプログラム - アプリのUI部分やWebでは上記のような処理が頻出 → Rxが有効に活用できる
サンプル - 数値の入力欄2つ - 計算ボタンをクリックして2値の加減乗除の計算をする - ↓こんなの
よくあるイベント処理の場合
書ける(当然)
何が問題? ※ バリデーションとかは別として
ここ
ここ
問題点 - 計算ボタンのクリックイベントで加減乗除を計算して、各要素 のテキストに反映している - ボタン自身がクリックされることによって変更される要素を知っていなければな らない - さらに、各要素に入力される値の規則も知っていなければならない -
要するに、結合が密 - 余りの計算を追加したくなったら、イベントハンドラが膨らむ - 追加/変更に弱い
Observerパターンを適用してみる
こんなオブジェクトを定義
イベント処理を置き換え
イベント処理を置き換え
イベントハンドラ部分の比較
イベントハンドラ部分の比較 - イベントハンドラ内に各要素の値更新のロジックが無くなった - data.suscribeで処理を外部から登録すれば良いので、別のファイルやオブジェ クトに分割も可能 - 余りの計算が追加されてもイベントハンドラに変更は発生しない - イベントを発生させるオブジェクトは自身の影響範囲を知らな
くて良い
RxJSで書くとこう
用語など
ストリーム - データの流れのこと - よくストリームが「川」、データが「桃」に例えられる - 個人的にはこの例えイマイチ... - 自動車の生産ラインとかに例えるほうが具体的 -
配列などから生成される他、イベントを一つのデータとみなし てイベントの発生を待ち受けるストリームなどもある
※ 公式サイトなどでよく見る図
オペレータ - Rxが提供しているメソッド群 - 自動車の生産ラインに例えるなら、次のようなもの - 自動車の塗装 (データの加工) - 品質検査
(データの選別) - ドアの取付 (ストリームの合成)
大きく分けると2種類
① データソースの定義
そのストリームに流れるデータは何から発生するか? (固定値、配列、時間経過、イベント...)
※ 公式サイトなどでよく見る図
② データの操作
データを受け取ったら何をするか? (加工、選別、合成、分岐...)
※ 公式サイトなどでよく見る図
subscribe - ストリームの処理のうち、最後の「加工結果の受け取り」にあ たるメソッド - 原則として、subscribeすることでストリーム内にデータが流れ 始める - next /
error / completeの3種類の処理が定義できる - next データが流れて来るたびに実行 - error ストリーム内でエラーが発生したときに実行 ストリームが終了する - complete ストリーム内を全てのデータが流れきったときに実行 ストリームが終了する
unsubscribe / dispose - ストリームには「勝手に終了するもの」と「勝手に終了しないも の(半永久的に続くもの)」がある。 - 配列から値を取り出して順にデータとして流す → 配列のデータを全て流したら終わり
- 2秒経ったらデータを流す → 2秒後にデータを流したら終わり - 1秒ごとにデータを流す → 常に次の1秒は存在するので半永久的に続く - イベントが発生したらデータを流す → イベントはいつまでも発生し得る = 半永久的に続く - subscribeで開始したデータの受け取りを明示的に終了させる ために使う。
処理の流れ データの 発生 加工、抽出 分岐、合成 データの 受け取り ストリームの 破棄 ※
繰り返し
Rxの特徴
メソッドチェーンによる簡潔な記述 - オペレータ一つが一つの処理になる → どこでなにをしているのか明確 - 複数の非同期処理でもネストの深さが一定に保てる ※ 1~100の合計を計算 ※
30秒毎に自動的にニュースを取得しにいく
豊富なオペレータ - 目的に応じた非常に多くのオペレータを提供 - RxJS 5系で90個ほど - 他言語では100を超えるものも多い - 実際によく使うのはせいぜい20~30個程度
- 他のオペレータで代用が効くものもあるので、全て覚える必要ななし - 制御構文に当たるものはRxが提供 開発者は流れてきたデータに対する処理に集中すればOK - 既存のプログラムとの互換性のためのユーティリティも提供し ている(JSで言えばPromiseとの相互変換など)
全てが非同期 - データの受け取りは必ず非同期的に行われる - ハマりポイントの一つ - subscribeして以降はデータが流れてくるたびに勝手に処理してくれる - 1つのストリームの中は同期的に処理が進む (map
-> filterと書いておけばがfilter -> mapの順で実行されることはない) - 複数の非同期処理を制御するためのオペレータもある - mergeMap 複数の非同期処理を並列実行 - concatMap 複数の非同期処理を直列実行 - switchMap 後勝ち。既存の処理をキャンセル - exhaustMap 先勝ち。新しい処理を実行させない。
適用可能範囲の広さ - 元々FRPを実現するために作られたライブラリ - FRPは汎用的なプログラミングパラダイム - メソッドチェーンの外にifやforを書かないプログラミングも十分 可能 - おすすめはしません
- 得意分野はリスト処理と非同期処理 - リスト処理だけなら最近は大抵の言語に実装されてるので... - 非同期処理の制御はかなり強力
Rxのデメリット
学習コストの高さ - そもそもプログラミングのパラダイムが異なるので当然といえ ば当然 - 一つの新しい言語を学んでいるようなもの - オペレータも少なくとも20~30は覚える必要がある - 処理に応じてRxを使うべきか言語構文を使うべきかの判断が
必要になる - Rx特有のハマりポイントも多い ※ 拡張性が低い、という批判もあるが個人的にはNo そういう場合、大抵は複数のデータを1本で管理しようとしている 1つのストリーム = 1つのデータ/操作を守っていれば拡張は容易
Rxの採用について
大前提として
Rx ≠ 銀の弾丸
Rx ≠ 銀の弾丸 - プログラミングパラダイム毎に得手不得手がある - どこにでも適用すれば便利になる、ということはない - 適用することが有効なところで使ってこそ活きる →
他のライブラリでも同じ - Rxでやれば簡単に書けるところはある - 逆に、Rxを使うと複雑になるところも当然ある - 「Rx使ってみたけどイマイチメリットが...?」 - 使い所間違っていませんか? - 適切に使い分けができるよう、自身の判断基準を養うところも 学習コスト
Rxを使ったほうが良い場合
言語のリスト処理が貧弱な場合 - 昔のAndroid Javaのパターン - ストリーム ≒ 配列はイメージしやすく適用が容易 - map,
filter, reduceなどが必要な場合に - 当然非同期的に結果を受け取ることになるので良し悪し - 言語組み込みのmap, filter, reduceは動的的なので間隔は若干異なる
非同期処理が必要な場合 - イベント処理 - UI上のユーザアクションはよくある非同期処理の例 - debounce, throttleはもちろん、多重クリックの制御や検知にも - API呼び出し
- こちらも代表的な非同期処理 - 特に複数のAPI呼び出しが絡む場合は非常に便利 - イベント処理同様、多重実行の制御が簡単 - 「このAPIのレスポンスを使って次のAPIを呼び出す」といった待ち受けも簡単 - 状態管理 - 動的に変更され得る状態は「状態が変更される」という非同期的なイベントを 持っている - Observerパターンが得意とするところ
Rxを使わないほうが良い場合
非同期処理がない、少ない - 非同期処理がないのに非同期処理を組み込む意味は...? - リスト処理が貧弱な場合は別 - 非同期処理がシンプルかつ少なく、言語標準の非同期処理が 簡単な言語なら採用しないという判断もあり - JavaScript
(Promise) - Go (goroutine)
Rx採用のすゝめ
Rxを採用するなら - 全てをRxで書こうとしない - 手続き型で簡単に書けるところをRxで置き換えても旨味がない - Rxで書いてみて、「これは手続きで書くほうが楽」と感じる処理は素直にそれ に従ったほうが良い - 慣れてくるとどちらが楽か何となくつかめる
- まずは小さく適用する - 慣れてないうちに書いたコードは実装にムリが出がち - 切り出せる部分に順次適用して行くのが吉 - できれば複数人で - これは個人的に一人で書いてて思ったこと - 同じことをするのに何パターンもの書き方がある - 「こんな書き方もできる」という引き出しが多いほうが良い - ペアプログラミングがかなり有効そうな気がする
まとめ
まとめ - Rxは非同期処理が得意なライブラリ - 複数の非同期処理が絡む場合に威力を発揮 - プログラミングパラダイムが異なるので学習コストはちょっと高 め - Rx
≠ 銀の弾丸 - 元言語と得手、不得手を比較して選定を
良いRxライフを!