Upgrade to Pro — share decks privately, control downloads, hide ads and more …

RxJS Real World

RxJS Real World

2017/6/17 ng-japan 2017で発表した資料です。

2bedb1eb8f841cd3c3ae584600b016e0?s=128

OKUNOKENTARO

June 17, 2017
Tweet

Transcript

  1. 3Y+43FBM8PSME +VO !OHKBQBO

  2. 0,6/0,&/5"30 'SPOUFOE&OHJOFFS 1JYFM(SJE*OD 5IFSFQSFTFOUBUJWFPGOHLZPUP

  3. 5IFDVSSFOUEFWFMPQNFOU GPSUIF"OHVMBSBQQMJDBUJPO JOPVSDBTF

  4. 8FVTF3Y+4BMPU

  5. 5IFFWFOUESJWFO"OHVMBS+4

  6. 5IFFWFOUESJWFO"OHVMBS+4 • $scope.$emit() • $rootScope.$broadcast() • $scope.$on()

  7. 5IFFWFOUESJWFO"OHVMBS+4 • $scope.$emit('eventName', value) • $rootScope.$broadcast() • $scope.$on()

  8. 0OUIFPUIFSIBOE JO"OHVMBS

  9. 5IFFWFOUESJWFO"OHVMBS w @Output() w &NJUCBTFEWBMVFFYDIBOHF w "1*BTTVNJOHBTUSFBN w @angular/http, @angular/router

  10. "SFZPVVTJOHtoPromise() UPPPGUFO

  11. -FUTVTF3Y+4JOTUFBE

  12. 0VSBQQMJDBUJPO w /VNCFSPG$PNQPOFOU w 0WFS  w /VNCFSPG4FSWJDF w 0WFS

     w 4UJMMJODSFBTJOH
  13. 0VSUFBN w 'SPOUFOE&OHJOFFST w QFPQMF %FTJHOFS w 4JNVMUBOFPVTEFWFMPQNFOUFWFSZEBZ w 1BSBMMFMEFWFMPQNFOUPGNVMUJQMFTDSFFOT

  14. $PNNPOMBOHVBHFJTOFFEFE JOBSDIJUFDUVSF

  15. 4IPVMEXFVTF'MVY

  16. -FUTVTF3Y+4CBTFE$234 JOTUFBE

  17. $PNNBOE2VFSZ3FTQPOTJCJMJUZ4FHSFHBUJPO UI Command Query Database Read Write

  18. $PNNBOE2VFSZ3FTQPOTJCJMJUZ4FHSFHBUJPO w .BJOMZQSPQPTFEGPSTFSWFSTJEF w 8FBEPQUFEJUUPDPOGSPOUDPNQMFYJUZ w 5IFSFBTPOGPSNBLJOHUIJTEFDJTJPOJTUIBU XFBSFQSBDUJDJOH%%%

  19. $234JO'SPOUFOE w 0OFTDSFFO0OF$PNNBOET2VFSJFT w :PVDBOTFFBMMUIBUZPVDBOEPPOUIBU TDSFFOCZMPPLJOHBUUIF$PNNBOET w *GZPVMPPLBUUIF2VFSJFT ZPVDBOTFFBMM UIFOFDFTTBSZWBMVFTGPSUIBUTDSFFO

  20. Angular @Component Commands Service Queries Service Repository Service Server-side

  21. AngularJS Directive GOD Service ! Server-side Server-side

  22. GOD ng-controller !!! Server-side Server-side

  23. Angular @Component Commands Service Queries Service Repository Service Server-side %JWJTJPOUPMPHJDBMMZDPOWFZUIFJOUFOUJPO

  24. Angular @Component Commands Service Queries Service Repository Service Server-side &WFSZUIJOHJTBTZODISPOPVTTUSFBN

    Sync call Sync call Sync request and async response Async stream Async stream
  25. &YBNQMFPGNVMUJQMF BTZODISPOPVTQSPDFTTJOH

  26. &YBNQMFPGGFUDIJOHVTFST Component Endpoint fetchUsers() .then(users => {}) 8JUIPVU3Y+4

  27. &YBNQMFPGGFUDIJOHVTFST 8JUI$2343Y+4 fetchUsers() fetchUsers() api.get() http.get() subscribe() subject.next() users$() Component

    Repository Queries Commands Endpoint ApiService
  28. 'PDVTPO"QJ4FSWJDF Component Repository Queries Commands Endpoint ApiService Endpoint ApiService

  29. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter 'PDVTPO"QJ4FSWJDF

  30. "MNPTUFWFSZUIJOHJTBTZOD HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter 5IJTJTUIFPOMZTZOD

  31. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Endpoint Endpoint Map .VMUJQMFTUSFBNT
  32. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService Endpoint

    Authority 1BSUJUJPOBOENFSHF
  33. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Adapter "OUJDPSSVQUJPOMBZFS
  34. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter ApiService Cache

    'FUDIPSDBDIF
  35. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Endpoint Endpoint Map w *OPSEFSUPLOPXBMMUIFFOEQPJOUT XFIBWFUPHFUUIFNBQQJOH JOBEWBODF w 8FXJMMQSPDFFEUPUIFOFYUQSPDFTTJOHCZVTJOHconcatMap() w "TZODISPOPVTMZDPNCJOFBSFRVFTUCPEZBOEUIFFOEQPJOU JOGPSNBUJPO
  36. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Endpoint Endpoint Map this.endpoint .endpoint$ .concatMap(ep => this.http.get(ep.url))
  37. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService Endpoint

    Authority w 8FIBWFUPIBOEMFUIFQSFTFODFPS BCTFODFPGBDDFTTBVUIPSJUZ w 5IFTUSFBNJTUFNQPSBSJMZCSBODIFEVTJOH partition()BOEBDDFTT
 BVUIPSJUZJTTUPSFE w "OEXFNFSHFBHBJO
 CZVTJOHmerge()
  38. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService Endpoint

    Authority const streams = somethingStream$ .partition(authority => authority.isAllowed) const [allowed$, denied$] = streams return Observable.merge( allowed$ .map(res => ({isAllowed: true, data: res})), denied$ .map(authority => ({isAllowed: false, data: autority})) )
  39. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Adapter w 5IFSFJTOPUZQFBOOPUBUJPOJOUIF SFTQPOTFGSPNUIFTFSWFS w "OEUIFQSPQFSUZOBNFNBZCFEJGpDVMUUP SFBE w 8FNBLFJUFBTZUPSFBECZQBTTJOHUIF BEBQUFSWJBconcatMap()
  40. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Adapter this.wrapedHttp .get(inputModel) .concatMap(allowedOrDenied => { if (isFailure(allowedOrDenied)) { return this.denied() } const adaptedResponse = this.adapt(allowedOrDenied.data.json()) this.cache.set(cacheKey, adaptedResponse) return this.allowed(adaptedResponse) })
  41. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter ApiService Cache

    w 8FBSFQSPDFTTJOHFGpDJFOUSFRVFTUTVTJOHDBDIF w 5IFTFSWJDFTZODISPOPVTMZSFUVSOTUIFDBDIFJGJUFYJTUT w 8FVTFObservable.of()UPUSFBUTZODISPOPVTWBMVFT BTTUSFBNT
  42. HttpService ApiService Endpoint Cache Endpoint Map Authority Adapter HttpService ApiService

    Adapter const cacheKey = inputModel.toCacheKey() if (this.cache.has(cacheKey)) { return this.allowed(this.cache.get(cacheKey)) } return this.wrapedHttp .get(inputModel) .concatMap(allowedOrDenied => { // })
  43. 8IBUXFEPOPUSFDPNNFOE

  44. /FTUFEDPNCJOF-BUFTU class SomeQueriesService { get methodB$(): Observable<[...]> { return Observable.combineLatest(

    this.methodA$, this.otherRepository.someModels$ ) } get methodA$(): Observable<[...]> { return Observable.combineLatest( this.repository.entities$, this.config.config$ ) } }
  45. class SomeQueriesService { get methodC$(): Observable<[...]> { return Observable.combineLatest( this.methodB$,

    this.greatRepository.niceValues$ ) } get methodB$(): Observable<[...]> { return Observable.combineLatest( this.methodA$, this.otherRepository.someModels$ ) } get methodA$(): Observable<[...]> { return Observable.combineLatest( this.repository.entities$, this.config.config$ ) } } /FTUFEDPNCJOF-BUFTUCFDPNFTWFSZDPNQMJDBUFE ,*44,FFQJUTIPSUBOETJNQMF
  46. 6TJOHSFDLMFTT#FIBWJPS4VCKFDU new BehaviorSubject(null)

  47. 6TJOHSFDLMFTT#FIBWJPS4VCKFDU new BehaviorSubject(null) new ReplaySubject(1)

  48. *UXJMMUSZUPVTFUP1SPNJTFJNNFEJBUFMZ someStream$ .take(1) .toPromise() .then(...)

  49. *UXJMMUSZUPVTFUP1SPNJTFJNNFEJBUFMZ const subscription = someStream$ .take(1) .subscribe(...) .BJOUBJOUIFTUSFBNBTNVDIBTQPTTJCMF CFDBVTF3Y+4JTBDPNNPOMBOHVBHFPGBTZODISPOPVTQSPDFTTJOH .FNPSZMFBLTBSFBWPJEFEXJUISubscription.unsubscribe()

  50. )PXUPMFBSO

  51. 4VHHFTUFETJUFT w 3Y+40GpDJBM w IUUQSFBDUJWFYJPSYKT w -FBSO3Y+4 w IUUQTXXXMFBSOSYKTJP

  52. $PEF(SJE IUUQTBQQDPEFHSJEOFU

  53. )BWFBOJDF3Y+4 5IBOLZPVGPSZPVSBUUFOUJPO