Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Rx入門
Search
ponday
November 21, 2017
Technology
1
1.3k
Rx入門
Rx勉強会@福岡 #0 発表資料
学習コストは高いけど使いこなせると強力だよっていうことを言いたかった。
ponday
November 21, 2017
Tweet
Share
More Decks by ponday
See All by ponday
関数型でGoFのデザインパターンやってみる
honda
1
1.1k
TypeScriptの型表現
honda
10
2.9k
Web Componentsの今
honda
1
380
これまでのReact、これからのReact
honda
0
280
Gatsbyお試し
honda
0
110
styled-components or emotion?
honda
0
630
Web ComponentsとAngular
honda
0
130
Atomic Design周りについての私見
honda
1
620
え、まだWeb Componentsを未来の技術だと思ってるの?
honda
2
740
Other Decks in Technology
See All in Technology
ドメインの本質を掴む / Get the essence of the domain
sinsoku
2
150
透過型SMTPプロキシによる送信メールの可観測性向上: Update Edition / Improved observability of outgoing emails with transparent smtp proxy: Update edition
linyows
2
210
ExaDB-D dbaascli で出来ること
oracle4engineer
PRO
0
3.8k
B2B SaaSから見た最近のC#/.NETの進化
sansantech
PRO
0
720
ISUCONに強くなるかもしれない日々の過ごしかた/Findy ISUCON 2024-11-14
fujiwara3
8
870
TypeScript、上達の瞬間
sadnessojisan
46
13k
SREによる隣接領域への越境とその先の信頼性
shonansurvivors
2
510
データプロダクトの定義からはじめる、データコントラクト駆動なデータ基盤
chanyou0311
2
280
Why App Signing Matters for Your Android Apps - Android Bangkok Conference 2024
akexorcist
0
120
[FOSS4G 2024 Japan LT] LLMを使ってGISデータ解析を自動化したい!
nssv
1
210
安心してください、日本語使えますよ―Ubuntu日本語Remix提供休止に寄せて― 2024-11-17
nobutomurata
1
990
Terraform CI/CD パイプラインにおける AWS CodeCommit の代替手段
hiyanger
1
240
Featured
See All Featured
Automating Front-end Workflow
addyosmani
1366
200k
Statistics for Hackers
jakevdp
796
220k
Testing 201, or: Great Expectations
jmmastey
38
7.1k
Git: the NoSQL Database
bkeepers
PRO
427
64k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
4 Signs Your Business is Dying
shpigford
180
21k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Designing on Purpose - Digital PM Summit 2013
jponch
115
7k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
44
2.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
654
59k
Gamification - CAS2011
davidbonilla
80
5k
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ライフを!