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
RxJS概要とリアクティブ アーキテクチャ
Search
dsuket
March 21, 2016
Technology
4
2.2k
RxJS概要とリアクティブ アーキテクチャ
ng-japan2016でのRxJSの話
dsuket
March 21, 2016
Tweet
Share
More Decks by dsuket
See All by dsuket
ぼくのアプリがカイゼンできない
dsuket
1
1.3k
Other Decks in Technology
See All in Technology
“それなりに”安全なWebアプリケーションの作り方
xryuseix
0
270
us-east-1 の障害が 起きると なぜ ソワソワするのか
miu_crescent
PRO
2
770
Copilotの精度を上げる!カスタムプロンプト入門.pdf
ismk
10
3.3k
Lazy Constant - finalフィールドの遅延初期化
skrb
0
110
ソフトウェア開発現代史: 55%が変化に備えていない現実 ─ AI支援型開発時代のReboot Japan #agilejapan
takabow
1
1.6k
[mercari GEARS 2025] Keynote
mercari
PRO
0
160
決済システムの信頼性を支える技術と運用の実践
ykagano
0
460
旧から新へ: 大規模ウェブクローラの Perl から Go への移行 / YAPC::Fukuoka 2025
motemen
1
560
AI時代におけるドメイン駆動設計 入門 / Introduction to Domain-Driven Design in the AI Era
fendo181
0
660
コード1ミリもわからないけど Claude CodeでFigjamプラグインを作った話
abokadotyann
1
160
"おまじない"はもう卒業! デバッガで探るSpring Bootの裏側と「学び方」の学び方
takeuchi_132917
0
110
ステートレスなLLMでステートフルなAI agentを作る - YAPC::Fukuoka 2025
gfx
0
140
Featured
See All Featured
Gamification - CAS2011
davidbonilla
81
5.5k
Raft: Consensus for Rubyists
vanstee
140
7.2k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
285
14k
Designing for Performance
lara
610
69k
The Pragmatic Product Professional
lauravandoore
36
7k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
508
140k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Making Projects Easy
brettharned
120
6.4k
The Cost Of JavaScript in 2023
addyosmani
55
9.2k
Speed Design
sergeychernyshev
32
1.2k
Code Review Best Practice
trishagee
72
19k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
660
Transcript
RxJS֓ཁͱ ϦΞΫςΟϒ ΞʔΩςΫνϟ ng-japan 2016 OpenWeb Technology Daisuke. Takaoka With
About me ߴԬେհ ελʔτΞοϓCTOɺٕज़ސɺٕज़૬ஊͳͲ ϑϩϯτ͔ΒΠϯϑϥ·Ͱ ࠷ۙόοΫΤϯυͰRxJSͬͯ·͢ Angular2ͬͯͳͷͰ ؒҧͬͯͯ͝צห͍ͩ͘͞ŋŋŋ @dsuket
TechFeed IUUQTUFDIGFFEJP *5ςΫϊϩδʔઐͷΩϡϨʔγϣϯαʔϏε
What’s TechFeed ? ڵຯͷ͋ΔτϐοΫΛબ͢ΔͱɺຖͦͷτϐοΫ ʹؔ࿈͢ΔχϡʔεΛϋΠϥΠτͰ͓ಧ͚͠·͢ɻ
ͪΖΜɺ ʮϦΞΫςΟϒϓϩάϥϛϯάʯ τϐοΫ͋Γ·͢ʂ https://techfeed.io/channels/Reactive%20Programming
techfeed.io Register now!!
RxJS֓ཁ
What RxJS? Reactive Extensions for JavaScript • .NETͷϥΠϒϥϦͱͯ͠ੜ • ࣌ؒ࣠ͷ͋ΔඇಉظετϦʔϜ
• ؔܕϦΞΫςΟϒϓϩάϥϛϯάʢFRPʣ • Angular2Ͱ࠾༻ʂ
Functional Reactive programming The introduction to Reactive Programming you've been
missing ݴ͍͍ͨ͜ͱશ෦͜͜ʹ͋Δ ʲ༁ʳ͋ͳ͕ͨٻΊ͍ͯͨϦΞΫςΟϒϓϩάϥϛϯάೖ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ʮStackoverflowͷൣతղʯ Conal Elliott • ࣌ؒΛ͔͚ͯμΠφϛοΫʹมԽ͢ΔɺϑΝʔετΫϥεͷ Ͱ͢ɻͦΕΒΛؔͷ in/out
ʹͯ͠Έ߹ΘͤΔ͜ͱ͕Ͱ͖· ͢ɻ͜ΕΛ Behavior ͱݺͼ·͢ɻ • Behavior ɺ੩తͳಈ࡞࣌ܭͷΑ͏ͳ࣌ؒͱ͍͍͔ͬͨͭ͘ͷ ϓϦϛςΟϒͳͷ͔Βߏஙͨ͠ޙɺॱ൪·ͨฒྻʹଓʹ͠ ·͢ɻnݸͷ Behavior ɺ࿈ଓͨ࣌ؒ͠ͷΑ͏ͳࢄతͳ nݸͷ ؔʹΑͬͯ߹͞Ε·͢ɻ • ͦͷ ࢄతݱΛදͨ͢Ίʹ ༗ݶ·ͨແݶʹग़ݱ͢Δετ ϦʔϜΛ࣋ͭ Event ͕͋Γ·͢ɻEvent ࣌ؒͱͷϖΞͰ͢ɻ ݩMSͷResearcherͰFRPͷ࢝ͱݴΘΕΔConal Elliottͷղઆɻ Α͘ࢀর͞ΕΔ͕ɺ৽ਓ͖Ͱͳ͍
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ʮReactive Manifestoʯ ϦΞΫςΟϒγεςϜͱ: ଈԠੑɺোੑɺྗੑɺϝοηʔδۦಈΛඋ͑Δ ϓϩδΣΫτϚωʔδϟϏδωεܥͷਓؒʹݟͤΔͷͷΑ͏ͩɻ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? "Rx = Observables + LINQ + Schedulers”
ɾObservables: σʔλετϦʔϜ ɾLINQ(Language-Integrated Query): ΫΤϦ ɾSchedulers: ฏߦੑ੍ޚ ͱͯॏͨ͘ɺզʑΛࠞཚͤ͞ΔϚΠΫϩιϑτతͳͷͩɻ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ඇಉظσʔλετϦʔϜΛ༻͍Δϓϩάϥϛϯά • ετϦʔϜͱ࣌ؒॱʹฒΜͩਐߦதͷΠϕϯτͷྻ • ετϦʔϜͷΠϕϯτΛඇಉظʹॲཧ • ετϦʔϜΛ߹ɺ࡞ɺϑΟϧλ͢Δศརͳؔ܈
• ܰྔͰԿͰετϦʔϜʹͰ͖Δ
ϘλϯΫϦοΫͷΠϕϯτετϦʔϜ ΫϦοΫΠϕϯτ ετϦʔϜͷྃ Τϥʔ ࣌ؒॱʹฒΜͩΠϕϯτྻΛඇಉظʹॲཧ͢Δ ετϦʔϜ ʹ Observable (*1) *1
ʢࢲ͜ΕΛഅ໊ࣛ͛ͨલͩͱײ͡ΔͷͰɺετϦʔϜͱݺͿɻ@andrestaltzʣ
μϒϧ ΫϦοΫ ͷྫ
Push vs Pull ObservableϒϩοΫͤͣʹෳͷΛ ϦΞΫςΟϒʹॲཧͰ͖ΔɻPromise++ What are the Reactive Extensions
for JavaScript (RxJS)? ୯ҰͷΓ ෳͷΓ 1VMMಉظతରܕ 0CKFDU "SSBZ 4FU .BQ 0CKFDU 1VTIඇಉظ3FBDUJWF 1SPNJTF 0CTFSWBCMF
Passive vs Reactive BarFoo͔Βૢ࡞͞Εɺ ঢ়ଶ͕֎෦ʹґଘ͢Δɻ BarFooͷΠϕϯτΛड͚ ࣗͰঢ়ଶΛཧ͢Δɻ ReactiveϓϩάϥϛϯάͰࣗʹΛͭϞδϡʔϧΛͭ͘Γɺ֎෦ ͷঢ়ଶΛมߋ͢Δ͜ͱΑΓϞδϡʔϧࣗͷػೳʹযΛ߹ΘͤΔɻ ؔ৺ͷʹܨ͕Δ
Observables › Cycle.js How Reactive Programming can help reduce code spaghetti Passive/Reactive ϓϩάϥϛϯάͷҧ͍ΛֶͿ
ͳͥReactiveProgramming͕ඞཁ͔ʁ ”” ݱͷΞϓϦɺߴʹΠϯλϥΫςΟϒͳମݧϢʔβʔʹ༩͑ ΔͨΊʹɺଟͷϦΞϧλΠϜΠϕϯτΛѻ͍ͬͯΔɻզʑ͜ ΕΛదʹऔΓѻ͏πʔϧΛ୳͓ͯ͠ΓɺϦΞΫςΟϒϓϩάϥ ϛϯά͕ͦͷ͑ͳͷͩɻ @andrestaltz
ͳͥReactiveProgramming͕ඞཁ͔ʁ ”” ϢʔβʔϦΞϧλΠϜΛظ͍ͯ͠ΔɻੈքpushʹҠಈ͠ ͨɻϢʔβʔզʑ։ൃऀ͕͍ͭ͘ͷΛ͍ͬͯΔɻ Intro to Rx - Why Rx?
Rx ʹ͍͍ͯΔͷɺ͍ͳ͍ͷ RxΛ͏͖ͷ • ϚεϘλϯΫϦοΫͷΑ͏ͳUIΠϕϯτɺΞϓϦέʔγϣϯͷΠϕϯτɺΠϯϑ ϥγεςϜͷΠϕϯτɺωοτϫʔΫΠϕϯτɺCEPͳͲͷඇಉظΠϕϯτॲཧશൠ Rx͕͑Δͷ • λεΫɺඇಉظγεςϜίʔϧͳͲ୯Ұͷඇಉظॲཧ ͔ͳ͍ͷ
• طଘͷಉظॲཧΛஔ͖͑Δ͚ͩͷͷ • ϝοηʔδΩϡʔͳͲɺγʔέϯγϟϧͳτϥϯβΫγϣϯ͕ඞཁͳͷ intro to Rx - When is Rx appropriate?
ECMAScript Observable • Observable ͕ ES7ʹఏҊ͞Ε͍ͯͯೖΓͦ͏ https://github.com/zenparsing/es-observable ೦ͷͨΊɺAngular1Ϣʔβʔʹࢥ͍ೖΕਂ͍ Object.observe ͱผw
ࠓͪΌΜͱೖΓͦ͏ʁ • RxJS(v5) ES7 Observable ४ڌ
Rxͷؒୡ Languages • RxJava, RxJS, Rx.NET, RxScala, RxGroovy, RxJRuby, •
UniRx, RxCpp, RxClojure, Rx.rb RxPY, RxKotlin, RxSwift Platforms and frameworks • RxNetty, RxAndroid, RxCocoa http://reactivex.io/languages.html
Other FRP libraries • Bacon.js • RxJSͷޙൃ FRPϥΠϒϥϦɻRxJSΑΓҰ؏ੑ͋Γɺ ͍͍͕͢ύϑΥʔϚϯεʹগ͋͠Γʁ •
Kefir • Bacon.jsͷ͞ΒʹޙൃɻলαΠζɺলϝϞϦɻ ͲͪΒES7 ObservableͱҟͳΓͦ͏ͳͨΊɺࠓޙ͕ඍົ
RxJSجૅ
RxJSͷҙ • ݱࡏ RxJS 4ܥͱ5ܥ͕͋ΓɺϦϙδτϦ͕ҧ͏ • 4ܥ: Reactive-Extensions/RxJS •
5ܥ: ReactiveX/RxJS ʢ·ͩbeta2ɻAngular2Ͱ࠾༻ʣ • v5ͰAPI͕౷ഇ߹͞Εͯ݁ߏมΘͬͯΔʂ • ᷿ͷυΩϡϝϯτ΄ͱΜͲ͕4ܥɻ֓೦େ͖͘มΘͬͯͳ͍͕ɻɻ • Migrating from RxJS 4 to 5 ඞಡ • ·ͩυΩϡϝϯτ͞Εͳ͍ଟ͍ͷͰιʔεಡΉඞཁ • ຊࢿྉ v5 ରԠͰઆ໌͠·͢
RxJSͷجຊ RxJS = Observables + Operators + Schedulers • Observable:
σʔλετϦʔϜ Rx.Observable.of / from / create ͳͲͰࣗ༝ʹ࡞ΕΔɻ • Operators: ΫΤϦ mapͱ͔filterͱ͔ɺObservableΛૢ࡞͢Δؔ • Schedulers: ฒߦੑͷίϯτϩʔϧ
جຊతͳॲཧ • ݩͷsource͔ΒObservableΛ࡞͠ɺΦϖϨʔλͰૢ ࡞͠ɺͦͷ݁ՌΛड͚ͯॲཧ͢Δɻ • ετϦʔϜ͔ΒσʔλΛड͚औΔ͜ͱΛSubscribeͱ͍ ͏ɻ • v5 Ͱ
ES7 ObservableͷΠϯλʔϑΣΠεʹ߹Θͤͨ • ʢجຊతʹʣSubscribe͢Δͱσʔλ͕ྲྀΕ࢝ΊΔɻ
؆୯ͳαϯϓϧ const stream = Rx.Observable.range(0,5) // 0,1,2,3,4 .map(x => x
* 3) // => 0,3,6,9,12 .filter(x => x%2); // => 3,9 stream.subscribe({ next: x => console.log(‘Next:' + x), error: err => console.error('Error:', err), complete: () => console.log('Completed'), }); => "Next:3" => "Next:9" => "Completed"
API֓ཁ • ͱʹ͔͘ΦϖϨʔλͷ͕ଟ͍ɻ • v4ܥͰ144ݸɺv5.0.0.beta.2Ͱ98ݸ • ੜɺมɺϑΟϧλϦϯάɺ݁߹ͳͲ • Ҏ߱Α͘͏ϐοΫΞοϓ
ࢀߟ: reactivex.io • RxͷΦϖϨʔλΛݴޠຖʹղઆ • ਤ͕ղɻ׳ΕΕಡΊΔ
ࢀߟ: RxMarbles • ΦϖϨʔλΛΠϯλϥΫςΟϒʹਤղ
ࢀߟ: ͦͷଞΑ͘ಡΉࢿྉ • RxJS/observable.md at master · Reactive-Extensions/RxJS • v4ͷAPIυΩϡϝϯτ
• RxJS/MIGRATION.md at master · ReactiveX/RxJS • v4͔Β5ͷϚΠάϨʔγϣϯΨΠυ • RxJS/src/operator at master · ReactiveX/RxJS • v5 ͷΦϖϨʔλҰཡʢsrcʣ • RxJS Advent Calendar 2015 • @bouzuya ͞ΜͷᕒͷಠΓΞυΧϨ
ੜ • Rx.Observable.of • ୯ҰͷΛͱΓɺͦΕΛฦ͢ετϦʔϜΛੜ • just/return ofʹٵऩ͞Εͨ • Rx.Observable.from
• ྻɺPromiseɺObservableͳͲΛऔΓɺͦΕΒෳͷͷετ ϦʔϜΛੜ • Rx.Observable.range / repeat • ࢦఆൣғɺ·ͨͷ࿈ଓͨ͠ετϦʔϜΛੜ • Rx.Observable.interval / timer • ҰఆִؒͰ܁Γฦ͢ • Rx.Observable.create • subscriberΛҾʹҙͷΛྲྀ͢ετϦʔϜΛੜ
ม • map (select) • Λม͢Δ • select v5
ͰഇࢭɻΛऔΔ߹ɺmapTo ʹɻ • mergeMap (flatMap) • map ݁Ռ͕Observableྻͷ߹Α͘͏ • v5 Ͱ mergeMap ʹɻObservableΛऔΔ߹ɺmergeMapTo ʹɻ • scan • reduceͬΆ͍͕ɺΛྲྀ͢ • groupBy • άϧʔϓ͚ʢׂʣ͢Δ • buffer / bufferCount / bufferTime • ࣌ؒͰΠϕϯτ·ͱΊΔ
ϑΟϧλϦϯά • filter (where) • ͳͲͰϑΟϧλϦϯά͢Δ • where v5
Ͱഇࢭɻ • first / last • ࠷ॳ࠷ޙͷ͚ͩΛऔΔ • skip / skipLast • ࢦఆͷnݸΛඈ͢ɻskipLast v5Ͱഇࢭ • take / takeLast • ࢦఆͷnݸΛऔಘ͢ΔɻtakeLast࠷ޙͷnݸɻ • distinct • ϢχʔΫʹͯ͠औಘ͢Δɻ • sample / debounce • ࢦఆִؒຖͷ࠷ޙͷΛऔಘ͢Δɻ
݁߹ • startWith • ॳظΛ࠷ॳʹૠೖ • merge • ετϦʔϜΛ݁߹͢ΔɻෳͰOK •
switch • ετϦʔϜΛॱʹྲྀ͢ • combineLatest • ෳͷετϦʔϜͷ࠷ޙͷΛ݁߹͢Δɻ • Ͳ͔͜1ͭͰདྷΕɺଞͷετϦʔϜͷۙͷͱ݁߹͢Δ • zip • ෳͷετϦʔϜͷ࠷ޙͷΛ݁߹͢Δɻ • શ෦ἧ͔ͬͯΒग़ྗ͞ΕΔɻ • and / then / when • v5Ͱഇࢭʁ
࣮ફRxJS
ζϯυίΩϤγ
·ͩ·ͩଓ͘ŋŋŋ
࡞ͬͯΈͨ https://jsbin.com/kecove/edit?js,console
ղઆ1: randomStream const randomStream = Rx.Observable .create(observer => { observer.next(!Math.floor(Math.random()*2));
observer.complete(); }); Everything is a stream Observable.create ͰɺϥϯμϜʹtrue/falseΛฦ͢ ετϦʔϜΛ࡞
ղઆ2: zundokoStream const zun = Rx.Observable.of('ズン'); const doko = Rx.Observable.of('ドコ');
return randomStream .flatMap(val => (val ? zun : doko)); “ζϯ” ͱ ”υί” Λฦ͢ετϦʔϜΛ࡞͠ɺ randomStreamͷʹΑͬͯΓସ͑Δɻ
ղઆ3: intervalStream return Rx.Observable.interval(400) .mergeMapTo(zundoko) .do(val => console.log(val)) .bufferCount(5, 1)
.takeWhile(val => val.join('') !== 'ズンズンズンズンドコ'); Observable.interval Ͱ 400msຖʹ܁Γฦ͢ετϦʔϜΛ࡞͠ ͦΕΛmargeMapToͰzundokoStreamʹஔ͖͑Δɻ doͰ్த݁ՌΛग़ྗͭͭ͠ɺbufferCount ͰskipΛ1Ͱ5ݸηο τɻtakeWhile ͰతͷจࣈྻʹͳΔ·Ͱ܁Γฦ͢ɻ
ղઆ4: subscribe const source = createStream(); source.subscribe({ next: () =>
{}, error: err => console.log('Error: ', err), complete: () => console.log('キ・ヨ・シ!'), }); ࡞ͨ͠StreamΛsubscribeͯ͠ɺྃ࣌ʹจࣈ ྻΛग़ྗ͢Δɻ
༨ஊ ಉ͜͡ͱ͕͜Ε1ߦ(87byte)ͰࡁΈ·͢ʢྦ ʢ͖ͬ͞ͷ764byteʣ for(n=3;n-64;console.log(n-64?(n|=2*Math.random())&1?' ドコ':'ズン':'キ・ヨ・シ!'))n<<=6 jsͰζϯυίΩϤγͷίʔυΰϧϑ
RxJS·ͱΊ • ࠓ͔ΒReactive ProgrammingΔͳΒRxJS 5ʂ • ΦϖϨʔλ͕ࢁ΄Ͳ͍͋ͬͯ͜ͳ͢ͷ ͍͠ɻ • ·͍ͣ͜͠ͱߟ͑ͣʹɺجຊతͳΦϖϨʔ
λͰ࡞ͬͯΈΔɻ ʢͦ͏͠ͳ͍ͱ͍ͭ·Ͱ͠ͳ͍ɾɾɾʣ
Reactive Architecture RxJS + 2
RxJS in Angular2 • Angular2ͰҰ෦ͰRxJSΛ࠾༻ • HTTP • EventEmitter •
ίϯϙʔωϯτΠϕϯτHTTPϦΫΤετΛ Observableͱͯ͠ѻ͑Δʂ • ViewͰObservableΛදࣔՄೳ
Angular2 Architecture Angular2Componentࢦ RxJSͬͯσʔλϑϩʔΛߟ͑ΒΕͳ͍͔
Reactive Architecture UNIDIRECTIONAL USER INTERFACE ARCHITECTURES ϢʔβʔΠϕϯτΛ୯Ұํͷσʔλϑϩʔͱ ͯ͠ѻ͏ΞʔΩςΫνϟͷҰཡΛհ FluxɺReduxɺBESTɺModel-View-Updateɺ Model-View-IntentɺNested
Dialogues
Flux • Store, View, Action, Dispatcher ͔ΒΔ • ViewReactComponentͷೖΕࢠʹͳΔ •
ViewͰϨϯμϦϯάͱΠϕϯτϋϯυϦϯάΛߦ͏
Redux • Singleton Store, Provider, Actions, Reducers • View ProviderReactҎ֎ʹAngularɺEmberͳͲͰՄ
• View͔ΒAction͕ݺΕɺActionຖʹReducerͰstateΛߋ৽͢Δ
Model-View-Update • “The Elm Architecture” ͱͯ͠ΒΕΔɻRedux͜Εʹinspire͞Εͨɻ • Model, View, Action,
UpdateΛComponentͱͯ͠֊ߏԽͰ͖Δɻ
Model-View-Intent • Cycle.js Ͱ࠾༻͞Ε ObservableΠϕϯτετϦʔϜΛσʔλϑϩʔͱ͢Δ • UserΠϕϯτϋϯυϥIntentͰએݴ͞ΕɺϨϯμϦϯάͱ • MVIComponentʹͳΓɺ֊తʹ͑Δ
Angular2ͰͷReactive Architectureͷݕ౼ • Angular2ͷComponentར༻͍ͨ͠ɻ֊Խͱؚ͔Ίɻ • MVIͷObservableத৺ͷߟ͑Αͦ͞͏ɻ • ComponentʹModelɼIntent૬ΛObservableͰೖΕͯΈΔɻ • ϞσϧΛObservableʹ͠ɺViewͰͦΕΛ͏
• ΠϕϯτϋϯυϦϯάAngularͷόΠϯσΟϯά͕ศརͳͷͰͦΕ Λ͏ɻ • όΠϯσΟϯάΛView͔Βग़͢͜ͱ͕ඞͣ͠ਖ਼ղͰͳ͍ͷͰɻʢؔ৺ͱٕज़ͷ ʣ
$PNQPOFOU Angular2 MVI 6TFS .PVTF *OUFOU 0CTFSWBCMF .PEFM Πϯελϯεม
0CTFSWBCMF 7JFX UFNQMBUF 4DSFFO formCtrl͔ΒϢʔβʔҙਤ ΛΠϯςϯτͱͯ͠Observableʹ Πϯςϯτ͔ΒΛऔΓग़͢ ObservableͳΠϯελϯεม ObservableมΛ asyncͰviewʹόΠϯυ
Angular2 MVI Sample ຯͳαϯϓϧ࡞ͬͯΈͨɻ • https://github.com/dsuket/angular2-mvi
@Component({ selector: 'bmi', styles: [require('./bmi.component.scss')], template:` <div class="bmi-calc"> <div class="weight">
<div class="label">Weight: </div> <input id="#weight" type=“range" [ngFormControl]="weightCtrl"> {{weight$ | async}} kg </div> <div class="height"> <div class="label">Height: </div> <input id="#height" type=“range" [ngFormControl]="heightCtrl"> {{height$ | async}} cm </div> <h3>BMI is {{bmi$ | async}}</h3> </div> `, directives: [FORM_DIRECTIVES], }) bmi.component.ts
export class BmiComponent { // Models private weight$; private height$;
private bmi$; // Controls private weightCtrl = new Control(); private heightCtrl = new Control(); constructor() { // Intents const weightChanges = this.weightCtrl.valueChanges; const heightChanges = this.heightCtrl.valueChanges; // Bind intents to models this.weight$ = weightChanges.map(Number).startWith(60); this.height$ = heightChanges.map(Number).startWith(170); this.bmi$ = this.weight$.combineLatest(this.height$) .map(this.calcBmi); } calcBmi(data) { const [weight, height] = data; const heightMeters = height * 0.01; return Math.round(weight / (heightMeters * heightMeters)); } } bmi.component.ts
ߟ Pros • ͳ͔ͳ͔ΩϨΠʹॻ͚ͦ͏ɻ • @Input ͳͲͰObservableΛΓͱΓͯ͠ɺComponentؒ࿈ܞ؆୯ ʹͰ͖ͦ͏ɻ Cons •
ຖճ async ॻ͘ͷ͕ͪΐͬͱ໘͍͘͞ɻ • ͦͦ͜ͷॻ͖ํ͕ͤͳͷ͔Ͳ͏͔Α͔͘Βͳ͍ɻɻ • ύϑΥʔϚϯεతʹͲ͏͔ؾʹͳΔɻ • ngFor ͕ Observable Λͦͷ··ѻ͑ͳ͍ͷ͕೦
༨ஊ ͖ͬ͞ͷ zundoko Λ Angular2 + MVI Ͱ࡞ͬͨ • dsuket/zundoko-angular
• Demo લηογϣϯͰ @shumpei ͕࡞ͬͨελʔλʔΩοτ͙͑͢Ͱ͖ͨɻ ͚Ͳɺશ෦ObservableͰ࡞ΔͷπϥΠŋŋŋ ࣌ؒͷ߹Ͱ݁ہී௨ͷόΠϯσΟϯάʹͳͬͨͱ͜Ζ
ࢀߟ • Cycle.js • Reactive Data Flow in Angular 2
• How to build Angular 2 apps using Observable Data Services - Pitfalls to avoid • Taking advantage of Observables in Angular 2 • todomvc-ng2-reactive • angular2-reactive-starter
·ͱΊ • ObservableES7Ͱ࠾༻͞Εͦ͏ͳͷͰɺࠓ ͔Β͓ͬͯ͜͏ʂ • ObservableΛத৺ͱͨ͠σʔλϑϩʔΞʔΩς ΫνϟࠓྲྀߦΔʂʁ • TechFeedͰτϨϯυΛ͍͔͚Α͏ʂ