ãã®èšäºã§ã¯ãããã¹ã¬ããã§å¥ã®ã¹ã¬ãããåŠçããæ¹æ³ããããå¿
èŠãªçç±ãããã³é«æ¬¡ãªãã¶ãŒããã«ïŒä»¥äžHOOïŒæŒç®åãããã«ã©ã®ããã«åœ¹ç«ã€ããèŠãŠãããŸãã
ã¹ã¬ããã§äœæ¥ããå Žåãå¥ã®äœæ¥ã®çµæãå€ãšããŠ1ã€ã®ã¹ã¬ããã«è»¢éããå¿
èŠãããå Žåã«ããçºçããŸãã ããšãã°ãçŸåšã®ã¹ã¬ããã§ajaxãªã¯ãšã¹ããå®è¡ããŠãã®ã¬ã¹ãã³ã¹ãåŠçããããããã€ãã®äžŠåãªã¯ãšã¹ããå®è¡ããŠããŒãªã³ã°ãå®è£
ãããããŸãã çŽæãªã©ã®ã¡ã«ããºã ã䜿çšããŠãã®ãããªåé¡ã解決ããããšã«å€ãã®äººãæ
£ããŠãããšæããŸãã ããããRxJSã䜿çšããŠãããã解決ããããšã¯å¯èœã§ããïŒ ãã¡ããããã¹ãŠãããªããèãããããã¯ããã«ç°¡åã§ãïŒ
äžé£ã®èšäºãRxJSã䜿çšãããªã¢ã¯ãã£ãããã°ã©ãã³ã°ã®åºç€ãïŒ
泚 ïŒèšäºã®çè«çãªéšåãç解ããããã«ã以åã®èšäºãèªãå¿
èŠã¯ãããŸããã芳枬å¯èœãªæŒç®åããã€ããäœã§ããããç¥ãå¿
èŠããããŸãã å®éã®éšåã§ã¯ã
2çªç®ã®èšäºã®äŸãæ¹è¯ã
ãŸã ã
åé¡
次ã®ã¿ã¹ã¯ãæ³åããŠã¿ãŸãããããµãŒããŒã«ã¢ã¯ã»ã¹ã§ãããã©ãããæ¯ç§èª¿ã¹ãå¿
èŠããããŸãã ã©ãããã°è§£æ±ºã§ããŸããïŒ
ãŸããã¿ã€ããŒã¡ãœããã䜿çšããŠã¹ããªãŒã ãäœæããŸãã
timer(0, 1000).subscribe({ next: console.log });
ã¿ã€ããŒã¡ãœããã¯ãååãšããŠ
intervalãšéåžžã«äŒŒãŠã
ãŸã ã ãããããããšã¯ç°ãªããã¹ã¬ããéå§ã¿ã€ã ã¢ãŠããèšå®ã§ããŸããããã¯ãæåã®ãã©ã¡ãŒã¿ãŒã«ãã£ãŠéä¿¡ãããŸãã 2çªç®ã®ãã©ã¡ãŒã¿ãŒã¯ãæ°ããå€ãçæãããééã瀺ããŸãã 2çªç®ã®ãã©ã¡ãŒã¿ãŒãæå®ãããŠããªãå Žåãã¿ã€ããŒã¯1ã€ã®å€ã®ã¿ãçæããã¹ããªãŒã ãçµäºããŸãã
ããªããšç§ã«ã¯ãµãŒããŒããªãã®ã§ããµãŒããŒãžã®ãªã¯ãšã¹ãããšãã¥ã¬ãŒãããé¢æ°ãæžãããšããå§ãããŸãã
const makeRequest = () => { return timer(1000).pipe( mapTo('success') ) }
ãã®ã¡ãœããã¯äœãããŸããïŒ ã¿ã€ããŒã¡ãœããã䜿çšããŠäœæãããã¹ããªãŒã ãè¿ããŸãããã®ã¡ãœããã¯ã1ç§ãçµéããŠçµäºããåŸã«å€ãçºè¡ããŸãã ã¿ã€ããŒã¡ãœããã¯æ°å€ã®ã¿ãçæãããããmapToæŒç®åã䜿çšããŠæååãsuccessãã«çœ®ãæããŸãã
ããã¯ãmakeRequestã¡ãœããã«ãã£ãŠäœæãããã¹ããªãŒã ã®å€èŠ³ã§ãã
ã¹ããªãŒã å
ã§makeRequestã¡ãœãããåŒã³åºããããã®è²¬ä»»ããªãã¶ãŒããŒã«å²ãåœãŠãããéžæã§ããŸãã
ãã®å ŽåãRxJSã®ãã¹ãŠã®å¯èœæ§ãæŒç®åã§äœ¿çšãããªãã¶ãŒããŒãäžèŠãªçŸ©åãã解æŸã§ãããããæåã®ã¢ãããŒããæãŸããã§ãã ã¿ã€ããŒã¡ãœããã䜿çšããŠãééããšã«ã¯ãšãªãå®è¡ããŸãã
timer(0, 1000).pipe( map(() => makeRequest()) ).subscribe({ next: console.log });
ãã®ãããªã³ãŒããå®è¡ãããšãconsole.logã§ãããã¹ããsuccessããå«ãã¡ãã»ãŒãžã§ã¯ãªããObservableåã®ãªããžã§ã¯ããåä¿¡ããŠââããããšãããããŸãã
ãããã§ã¯ã¹ããªãŒã ãè¿ããããçãã¯éåžžã«æåŸ
ãããŠããŸãã ã¹ããªãŒã ãæ©èœãããã«ã¯ããµãã¹ã¯ã©ã€ãããå¿
èŠããããŸãã ããŠã
ãããããªãæ¹æ³ãèŠãŠã¿ãŸãããïŒ
timer(0, 1000).pipe( map(() => makeRequest()) ).subscribe({ next: observable => observable.subscribe({ next: console.log }); });
äžèšã®äŸã®åé¡ã¯ããµãã¹ã¯ãªãã·ã§ã³ã§ãµãã¹ã¯ãªãã·ã§ã³ãååŸããããšã§ãã ãããããã§ãŒã³ã§è€æ°ã®ãªã¯ãšã¹ããè¡ãããå Žåã¯ã©ãã§ããããïŒ ãŸãã¯ãããæç¹ã§å
éšã®ãããŒã®ãµãã¹ã¯ãªãã·ã§ã³ã解é€ããå¿
èŠãããå Žåã¯ã©ããªããŸããïŒ ãã®å Žåãã³ãŒãã¯ãŸããŸãã麺ãã«äŒŒãŠããŸãã ãã®åé¡ã解決ããããã«ãRxJSã«ã¯HOOãšåŒã°ããç¹å¥ãªæŒç®åããããŸãã
ããŒ
HOOã¯ãå€ãšããŠã¹ããªãŒã ãåãå
¥ããç¹å¥ãªã¿ã€ãã®ã¹ããŒãã¡ã³ãã§ãã ãã®ãããªæŒç®åã®1ã€ã«mergeAllã¡ãœããããããŸãã
ã¹ããªãŒã ãmergeAllã«å°çãããšããµãã¹ã¯ã©ã€ãããŸãã ãªãã¬ãŒã¿ãŒããµãã¹ã¯ã©ã€ãããã¹ããªãŒã ã¯ãå
éšãšåŒã°ããŸãã ãªãã¬ãŒã¿ãŒãå€ãšããŠä»ã®ãããŒãåãåãã¹ããªãŒã ã¯ãå€éšãšåŒã°ããŸãã
å
éšã¹ã¬ãããå€ãçæãããšãmergeAllã¯ãã®å€ãå€éšã¹ã¬ããã«ããã·ã¥ããŸãã ãããã£ãŠãæåã§ãµãã¹ã¯ã©ã€ãããå¿
èŠããªããªããŸãã å€éšã¹ããªãŒã ã®è³Œèªã解é€ãããšãmergeAllã¯å
éšã¹ããªãŒã ã®è³Œèªãèªåçã«è§£é€ããŸãã
mergeAllã䜿çšããŠäŸãæžãæããæ¹æ³ãèŠãŠã¿ãŸãããã
timer(0, 1000).pipe( map(() => makeRequest()) mergeAll() ).subscribe({ next: console.log });
äžèšã®äŸã§ã¯ãå€éšã¹ããªãŒã ã¯ã¿ã€ããŒã¹ããŒãã¡ã³ãã«ãã£ãŠäœæãããŸããã ãŸãããããæŒç®åã§äœæããããããŒã¯å
éšã§ãã äœæãããåã¹ã¬ããã¯ãmergeAllã¹ããŒãã¡ã³ãã«åé¡ãããŸãã
çµã¿åããããã+ mergeAllã¯éåžžã«é »ç¹ã«äœ¿çšããããããRxJSã«ã¯mergeMapã¡ãœããããããŸãã
timer(0, 1000).pipe( mergeMap(() => makeRequest()) ).subscribe({ next: console.log });
å€éšã¹ã¬ãããå€ãçæãããšãmergeMapãªãã¬ãŒã¿ãŒã¯æž¡ãããã³ãŒã«ããã¯é¢æ°ãåŒã³åºããŠãæ°ããã¹ã¬ãããçæããŸãã 次ã«ãmergeMapã¯çæãããã¹ããªãŒã ã«ãµãã¹ã¯ã©ã€ãããŸãã
mergeAll / mergeMapæŒç®åã®ç¹æ§ã¯ãå¥ã®ã¹ããªãŒã ãããã«å°éãããšããµãã¹ã¯ã©ã€ãããããšã§ãã ãããã£ãŠãå€éšã¹ããªãŒã ã§ã¯ãäžåºŠã«è€æ°ã®å
éšã¹ããªãŒã ããå€ãååŸã§ããŸãã 次ã®äŸãèŠãŠã¿ãŸãããã
timer(0, 1000)
ããã¯ãmergeMapæŒç®åã䜿çšããªãå Žåã®å€éšã¹ããªãŒã ã®å€èŠ³ã§ãã
ãããã£ãŠãmergeMapã®å ŽåïŒ
timer(0, 1000).pipe( mergeMap(() => interval(1000)) )
æ¯ç§ãæ°ããå
éšã¹ã¬ãããäœæãããmergeMapããµãã¹ã¯ã©ã€ãããŸãã ãããã£ãŠãå€æ°ã®å
éšã¹ã¬ãããåæã«åäœãããã®å€ã¯å€éšã«ãªããŸãã
泚 ïŒmergeMapã«ã¯æ³šæããŠ
ãã ãã ãæ°ããå
éšã¹ã¬ããã¯ãå€éšã¹ã¬ãããããµãã¹ã¯ã©ã€ãã解é€ãããŸã§æ©èœããŸãã äžèšã®äŸã§ã¯ãå
éšã¹ã¬ããã®æ°ã¯æ¯ç§å¢å ããŠããŸããæçµçã«ã¯ãã³ã³ãã¥ãŒã¿ãŒãè² è·ã«å¯Ÿå¿ã§ããªãã»ã©å€ãã®ã¹ã¬ãããååšããå¯èœæ§ããããŸãã
concatAll / concatMap
mergeMapã¡ãœããã¯ãå
éšã¹ã¬ããã®å®è¡é åºãæ°ã«ããªãå Žåã«æé©ã§ãããå¿
èŠãªå Žåã¯ã©ãã§ããããïŒ åã®ãµãŒããŒããã®å¿çãåä¿¡ããåŸã«ã®ã¿ã次ã®ãµãŒããŒãªã¯ãšã¹ããå®è¡ããããšããŸããïŒ
ãã®ãããªç®çã«ã¯ãHOOæŒç®åconcatAll / concatMapãé©ããŠããŸãã å
éšã¹ã¬ããã«ãµãã¹ã¯ã©ã€ããããã®ãªãã¬ãŒã¿ãŒã¯ãçµäºãããŸã§åŸ
æ©ãã次ã®ã¹ã¬ããã«ã®ã¿ãµãã¹ã¯ã©ã€ãããŸãã
ããã¹ã¬ããã®å®è¡äžã«æ°ããã¹ã¬ãããå°éãããšãåã®ã¹ã¬ãããå®äºãããŸã§ãã®ã¹ã¬ããããã¥ãŒã«çœ®ãããŸãã
äžèšã®äŸã§ã¯ãã¿ã€ããŒã¡ãœããã䜿çšããŠ2ã€ã®ã¹ã¬ãããäœæããŸãã ããããããããããã«ãmapToæŒç®åã䜿çšããŠç°ãªãå€ã衚瀺ããŸããã æåã®ã¹ã¬ããã¯1ãçæãã2çªç®ã®ã¹ã¬ããã¯2ãçæããŸããofã¡ãœããã䜿çšããŠå€éšã¹ã¬ãããäœæããã2ã€ã®ç£èŠå¯èœãªå
¥åãå
¥åãšããŠåãåããŸãã
concatAllã¹ããŒãã¡ã³ãã¯æåã«firstInnerObservableãåãåããããã«ãµãã¹ã¯ã©ã€ããããããå®äºããã®ãåŸ
ã¡ãŸããããã¯ãsecondInnerObservableã«æåã«ãµãã¹ã¯ã©ã€ãããåŸã®ã¿ã§ãã å€éšã¹ããªãŒã ã¯æ¬¡ã®ããã«ãªããŸãã
concatAllãmergeAllã«çœ®ãæãããšãã¹ããªãŒã ã¯æ¬¡ã®ããã«ãªããŸãã
of( firstInnerObservable, secondInnerObservable ).pipe( mergeAll() ).subscribe({ next: console.log });
switchAll / switchMap
ãã®æŒç®åã¯ãæ°ããã¹ããªãŒã ãåä¿¡ãããšããã«ä»¥åã®ã¹ããªãŒã ãããµãã¹ã¯ã©ã€ãã解é€ããæ°ããã¹ããªãŒã ããµãã¹ã¯ã©ã€ããããšããç¹ã§ã以åã®ãã®ãšã¯ç°ãªããŸãã
äžèšã®äŸã䜿çšããconcatAllãswitchAllã«çœ®ãæããŠãå€éšãããŒã®åäœã確èªããŸãã
of( firstInnerObservable, secondInnerObservable ).pipe( switchAll() ).subscribe({ next: console.log });
2çªç®ã®å
éšã¹ããªãŒã ã®å€ã®ã¿ãå€éšã¹ããªãŒã ã«å
¥ããŸããã ããã¯ãswitchMapã2çªç®ã®ã¹ã¬ãããåãåã£ããšãã«ãæåããswitchMapããµãã¹ã¯ã©ã€ããããŠããªãããã§ãã
ããã¯ãã€å¿
èŠã§ããïŒ ããšãã°ãããŒã¿æ€çŽ¢ãå®è£
ããå Žåã ãµãŒããŒããã®åçããŸã å°çããŠããããæ¢ã«æ°ãããªã¯ãšã¹ããéä¿¡ããŠããå Žåãåã®ãªã¯ãšã¹ããåŸ
ã€å¿
èŠã¯ãããŸããã
ææ°/ææ°ããã
exhaustã¯switchAllã¹ããŒãã¡ã³ãã®æ£å察ã§ããããã®åäœã¯concatAllã«äŒŒãŠããŸãã ã¹ããªãŒã ã«ãµãã¹ã¯ã©ã€ããããã®ã¡ãœããã¯ãã¹ããªãŒã ãå®äºãããŸã§åŸ
æ©ããŸãã æ°ããã¹ããªãŒã ãå±ããšãããã¯åã«ç Žæ£ãããŸãã
of( firstInnerObservable, secondInnerObservable ).pipe( exhaust() ).subscribe({ next: console.log });
äžèšã®äŸã§ã¯ããã®æç¹ã§ãªãã¬ãŒã¿ãŒãæåã®ã¹ã¬ããã®å®äºãåŸ
ã£ãŠããŠãåã«2çªç®ã®ã¹ã¬ãããããããããããããã¥ãŒã¹ã¯ååŸããŸããã§ããã
å€ãã®äººãçåãæã£ãŠãããšæããŸãããã€ãã®ãããªè¡åãå¿
èŠã«ãªãã®ã§ããããïŒ è¯ãäŸããã°ã€ã³ãã©ãŒã ã§ãã çŸåšã®èŠæ±ãå®äºãããŸã§ãè€æ°ã®èŠæ±ããµãŒããŒã«éä¿¡ããããšã¯æå³ããããŸããã
ç§ãã¡ã¯ã¢ããªã±ãŒã·ã§ã³ãå®æãããŠããŸã
2çªç®ã®èšäºã® äŸãæãåºã
ãŸã ã ãã®äžã§ãGitHubã§æ€çŽ¢ãå®è£
ããmergeMapæŒç®åã䜿çšããŠãµãŒããŒã«ãªã¯ãšã¹ããéä¿¡ããŸããã ããã§ããã®æŒç®åã®æ©èœãããããŸãããç§ãã¡ã®å Žåãæ¬åœã«é©ããŠããŸããïŒ
fromEvent(input, 'keyup').pipe( debounceTime(700), map(event => event.target.value), filter(val => val.length > 2), distinctUntilChanged(), mergeMap(value => { return from(getUsersRepsFromAPI(value)).pipe( catchError(err => of([])) ) }) ).subscribe({ next: reps => recordRepsToList(reps) })
GitHubãµãŒããŒãéåžžã«éè² è·ã«ãªããå¿çã®åŠçã«æéãããããšä»®å®ããŸãããã ãã®å Žåãäœãåé¡ã«ãªãå¯èœæ§ããããŸããïŒ
ãŠãŒã¶ãŒãããŒã¿ãå
¥åããåçãåŸ
ããã«æ°ããããŒã¿ãå
¥åãããšããŸãã ãã®å Žåã2çªç®ã®èŠæ±ããµãŒããŒã«éä¿¡ããŸãã ãã ããæåã®èŠæ±ã«å¯Ÿããåçãããæ©ãæ¥ãããšãä¿èšŒãã人ã¯ããŸããã
mergeMapãªãã¬ãŒã¿ãŒã¯å
éšãããŒãåŠçããé åºãæ°ã«ããªããããæåã®èŠæ±ã2çªç®ã®èŠæ±ãããåŸã«å®è¡ãããå Žåãå®éã®ããŒã¿ãæ¶å»ããŸãã ãããã£ãŠãmergeMapã¡ãœãããswitchMapã«çœ®ãæããããšãææ¡ããŸãã
fromEvent(input, 'keyup').pipe( debounceTime(700), map(event => event.target.value), filter(val => val.length > 2), distinctUntilChanged(), switchMap(value => { return from(getUsersRepsFromAPI(value)).pipe( catchError(err => of([])) ) }) ).subscribe({ next: reps => recordRepsToList(reps) })
ãŠãŒã¶ãŒãæ°ããããŒã¿ãå
¥åãããšãswitchMapã¯ä»¥åã®ã¹ããªãŒã ãããµãã¹ã¯ã©ã€ãã解é€ããæ°ããã¹ããªãŒã ããµãã¹ã¯ã©ã€ãããŸãã
ãµãŒããŒãå¿çãããŸã§ãhttpãªã¯ãšã¹ãããã³ã°ãç¶ããããšã«æ³šæããŠãã ããã ããããå
éšã¹ããªãŒã ãããµãã¹ã¯ã©ã€ããããŠããªããããçãã¯å€éšã¹ããªãŒã ã«åé¡ãããŸããã
泚 ïŒAngularã䜿çšããHttpClientã䜿çšããŠhttpã䜿çšããå Žåããªã¯ãšã¹ãèªäœããã£ã³ã»ã«ããããšã¯ã§ããŸããã HttpClientã¯ãç»é²è§£é€æã«ãããè¡ãããšãã§ããŸãã
httpããã£ã³ã»ã«
ãã§ããAPIã«ã¯ã
AbortControllerã䜿çšããŠhttpãªã¯ãšã¹ãããã£ã³ã»ã«ããæ©èœããã
ãŸã ã switchMapæŒç®åãšçµã¿åããããšããã®æ©èœã¯ãŠãŒã¶ãŒãã©ãã£ãã¯ãç¯çŽããŸãã
ãã®äŸãå°ãæžãæããŸãããã ãããŠããã§ããåŒã³åºããobservableã§ã©ããããã¡ãœãããäœæããŸãã
const createCancellableRequest = (url) => {
ãŸããgetUsersRepsFromApiã¡ãœãããå€æŽããŸãã
const getUsersRepsFromAPI = (username) => { const url = `https://api.github.com/users/${ username }/repos`; return createCancellableRequest(url); }
çŸåšããã®ã¡ãœããã¯promiseã§ã¯ãªããobservableãè¿ããŸãã ãããã£ãŠãswitchMapã®fromã©ãããŒãåé€ããŸãã
switchMap(value => { return getUsersRepsFromAPI(value).pipe( catchError(err => of([]) ) )
泚 ïŒRxJSããŒãžã§ã³6.5ã§ã¯ã
fromFetchã¹ããŒãã¡ã³ããè¿œå ãããããèªäœã
å
éšã§ abortã¡ãœãããåŒã³åºããããç¬èªã®ããã€ã¯ããèšè¿°ããå¿
èŠããªããªããŸããã
ããã ãã§ãïŒ ãã¹ãŠã®ãµã³ãã«ã³ãŒãã¯
ããã«ãããŸã ã
ãããã«
ä»æ¥ã¯ãHOOãšã¯äœãããã®ã«ããŽãªã®éåžžã«äŸ¿å©ãªæŒç®åãããã€ãèŠãŠããŸããã ãã¡ããããããã¯ãã¹ãŠãšã¯çšé ããã®ã§ããã ãã詳现ãªæ
å ±ã«ã€ããŠã¯ãRxJSã®
ããã¥ã¡ã³ããã芧ã«ãªãããšããå§ãã
ãŸã ã
次ã®èšäºã§ã¯ãããããšã³ãŒã«ãã®ãªãã¶ãŒããã«ã®éããæ€èšããäºå®ã§ãã
æåŸã«ãHOOãããããããµãã¹ã¯ãªãã·ã§ã³ã§ãµãã¹ã¯ãªãã·ã§ã³ã䜿çšããªãã§ãã ããïŒ