ã¯ãããïŒã«ã±ãã·ã®æ°ç±³ã¡ã³ããŒããªãŒã¹ãã£ã³ãšç³ããŸãã æ²çžããåäžããŠãããŸãïŒ æŠèŠ RxJS ã® mergeMap ãš switchMap ã®éããšäœ¿ãæ¹ã«ã€ããŠè§£èª¬ããŸãã èæ¯ Observable ã䜿ã£ãŠãããšãå¿
ãçŽé¢ããåé¡ããããŸããããã¯ã è€æ°ã® Observable ãã©ããã£ãŠäžç·ã«å®è¡ã§ããã ããšããåé¡ã§ãã ãšãã Observable ã®åŠçãçµãã£ãåŸã«ããã®ããŒã¿ãå
ã«ãå¥ã® Observable ã§ããã«éåæåŠçãããããšã¯éçºè
ãšããŠå€ã
ãããŸãã Promise ã® then ã§ãŸãå¥ã® Promise ãè¿ããŠãã§ãŒã³ããŠããã®ãšåãããšã§ãã ããããRxJS ã§ã¯ã Promise ãšéã£ãŠ Observable ãçŽåã«ãã§ãŒã³ããã®ã«äœ¿ã pipe ã® OperatorFunction ãè€æ°ååšããŸãã代衚çãªã®ã¯ã mergeMap ã mergeWith ãããã³ switchMap ã§ãã ãªã RxJS ã«ã¯è€æ°ã®ãã§ãŒã³ææ³ãååšããã®ã ãã®çåã¯æ¹§ããŸãããïŒ ãã®çåã«çããããã«ã¯ãŸãã Observable ãš Promise ã¯ã©ãç°ãªãã®ãèããå¿
èŠããããŸãã çè
ã«èšãããã°ã Observable ã®æã倧ããªéãã¯ã æªè§£æ±ºã® Observable ã®åŠçãåãæ¶ããã€ãŸãæ¢ããããšãç°¡åã«ã§ããç¹ ã§ãããã Promise ã§ã¯ã Promise ã解決ããŠããã®äžã§å®è¡ãããåŠçãåãæ¶ãæ¹æ³ããããŸããã以äžã®ã³ãŒããèŠãŸãããã const promise = new Promise((resolve) => { let count = 0; setInterval(() => console.log( `Loading ${++count} seconds.` ), 1000); setTimeout(resolve, 5000); } ); promise.then(() => console.log( "Resolved!!" )); èªè
ã¯èªãã§ãåããããšæããŸããããã®ã³ãŒããå®è¡ããŠã¿ããšã以äžã®ããã«ã Promise ã解決ãããåŸã§ãããã°ãåºç¶ããã®ã§ãã åãäŸã Observable ã§æžããŸãã import { Observable } from "rxjs" ; const observable$ = new Observable((observer) => { let count = 0; const interval = setInterval(() => console.log( `Loading ${++count} seconds.` ), 1000); setTimeout(() => { observer.next( "Timeout ended." ); observer.complete(); } , 5000); return () => clearInterval(interval); } ); observable$.subscribe( { next: console.log, complete: () => console.log( "Completed!" ) } ); Observable ã® executor 颿°ããæ»ãå€ãšããŠãã® interval ãã¯ãªã¢ãã颿°ãè¿ãã®ã§ãããããã Observable ã解決ïŒcompleteïŒãããæã«åŒã°ããã®ã§ãã ãããšã Promise ãšéã£ãŠæ°žé ã«ç¶ã interval ãæ®ãããŸããã ãã® åŸçä»ã ã®æ©èœãã Observable ã®éåžžã«åªãããšãããªã®ã§ã ã ãããŠãæ¬èšäºã«ã€ãªããéšåã§ããããã®åŸçä»ããããããããã Observable ããã§ãŒã³ããæã®ææ³ãçšéã«ãã£ãŠç°ãªãã®ã§ãã mergeMap ãšã¯äœã mergeMap ã¯ãmap ãšäŒŒãŠããŸãããç°¡åã«ãããšãäžã€ã® Oberservable ããæµããããŒã¿ãéã Observable ã«æµããã§ãŒã³ OperatorFunction ãªã®ã§ãã 以äžã®äŸãèŠãŠã¿ãŸãããã import { fromEvent, scan, mergeMap, interval, takeWhile, tap, combineLatest, of } from "rxjs" ; const docClick$ = fromEvent( document , "click" ); const clickCount$ = docClick$.pipe( scan((acc) => acc + 1, 0), tap((count) => console.log( `Document was clicked ${count} time(s).` )) ); clickCount$ .pipe( mergeMap((clickCount) => { const intervalPerClickCount = [ of(clickCount), interval(500).pipe(takeWhile((i) => i < 5)) ] ; return combineLatest(intervalPerClickCount); } ) ) .subscribe(( [ clickCount, i ] ) => console.log( `mergeMap: Click no ${clickCount} , interval count: ${i} ` )); document ãã¯ãªãã¯ãããšãã¯ãªãã¯ããåæ°ããŸã clickCount$ ã§è¶³ãç®ããŸãã ããããã mergeMap ã䜿ã£ãŠæ°ãã Observable ãè¿ããŸãã ãã®æ°ãã Observable ã¯ã combineLatest ã§åãããäºã€ã® Observable ã of(clickCount) ãš interval ã§ãã èŠããã«ã mergeMap ã§ Observable<number> ã Observable<[number, number]> ãšãããµãã«å€ããŠããŸãã 詊ããŠã¿ã document ãäžåã¯ãªãã¯ãããšä»¥äžã®ããã«åºåãããŸãã Document was clicked 1 time(s). mergeMap: Click no 1, interval count: 0 mergeMap: Click no 1, interval count: 1 mergeMap: Click no 1, interval count: 2 mergeMap: Click no 1, interval count: 3 mergeMap: Click no 1, interval count: 4 document ã 2 åé£çºã§ã¯ãªãã¯ãããšä»¥äžã®ããã«ãã°ãåºåãããŸãã Document was clicked 1 time(s). Document was clicked 2 time(s). mergeMap: Click no 1, interval count: 0 mergeMap: Click no 2, interval count: 0 mergeMap: Click no 1, interval count: 1 mergeMap: Click no 2, interval count: 1 mergeMap: Click no 1, interval count: 2 mergeMap: Click no 2, interval count: 2 mergeMap: Click no 1, interval count: 3 mergeMap: Click no 2, interval count: 3 mergeMap: Click no 1, interval count: 4 mergeMap: Click no 2, interval count: 4 ããã§éèŠãªèгå¯ã§ããã 2 åç®ã®ã¯ãªãã¯ããã£ãŠãã1 åç®ã®ã¯ãªãã¯ãå
ã«ãã combineLatest ã® Observable<[number, number]> ã¯æåŸãŸã§ç¶ãã®ã ãšããçµæãèšæ¶ã«çããŠãããŸãããã switchMap switchMap 㯠mergeMap ãšåãããã«ãäžæµã® Observable ãæ°ãã Observable ã«åãããŸãã ããããéèŠãªéãããããŸãã switchMap ã¯ãäžæµã®æãææ°ãå€ãã®ã¿ãšã£ãŠãäžæµã®æ°ãã Observable ã«æµãã®ã§ã ã ããšãã以åã®å€ã«åºã¥ããŠæµããäžæµã® Observable ããŸã 解決ãããŠããªããšããŠãã ãããã® Observable ãæ¢ããã®ã§ã ã äžèšã®ãœãŒã¹ã³ãŒãã§ mergeMap ã䜿ãããŠãããšããã switchMap ã«ããŠã¿ãŸãããã clickCount$ .pipe( switchMap((clickCount) => { const intervalPerClickCount = [ of(clickCount), interval(500).pipe(takeWhile((i) => i < 5)) ] ; return combineLatest(intervalPerClickCount); } ) ) .subscribe(( [ clickCount, i ] ) => console.log( `switchMap: Click no ${clickCount} , interval count: ${i} ` )); ãããå®éšããŠã¿ãŸãããïŒ è©ŠããŠã¿ã 1 åã ãã¯ãªãã¯ããŠã¿ã Document was clicked 1 time(s). switchMap: Click no 1, interval count: 0 switchMap: Click no 1, interval count: 1 switchMap: Click no 1, interval count: 2 switchMap: Click no 1, interval count: 3 switchMap: Click no 1, interval count: 4 mergeMap ãšåãçµæã§ãã 2 åé£çºããŠã¯ãªãã¯ããŠã¿ã Document was clicked 1 time(s). Document was clicked 2 time(s). switchMap: Click no 2, interval count: 0 switchMap: Click no 2, interval count: 1 switchMap: Click no 2, interval count: 2 switchMap: Click no 2, interval count: 3 switchMap: Click no 2, interval count: 4 ãªãã»ã©ïŒ**æåŸã®ã¯ãªãã¯ã ãã5 åã® interval ãåºãã®ã§ãïŒ ãŸãšã ãããŸã§ mergeMap ãš switchMap ã®éãã解説ããŠããŸãããããããã§ããããïŒ äŒŒããããªå¹æãããã®ã«ãæŽç¶ãªéããããã®ã§ãçè
ã¯ç¥ã£ãæã«é©ããŸããã ãã®éããç¥ããã«ã³ãŒããæžããŠãããšãè§£ããªããšã©ãŒãèµ·ããããªæ°ãããŸãã ããšãã°ãHTTP ãªã¯ãšã¹ãã§ã¯ãªãã¯ã«å¯ŸããŠãã°ãèšé²ããããæã«ãã©ãã䜿ãã°ãããšæããŸããïŒ ããžãã¹ã¢ãã«ã«ãããã®ã§ããã switchMap ã ãšããã°ã®ãªã¯ãšã¹ãããŸã çµãã£ãŠããªãã®ã«ããŠãŒã¶ãŒããŸãã¯ãªãã¯ãããšãåã®ãã°ã®ãªã¯ãšã¹ãããã£ã³ã»ã«ããã æåŸã®ã¯ãªãã¯ã ãããã°ã«æ®ãçµæã«ãªãã®ã§ã ããªã®ã§ã mergeMap ãåããŠããã§ãããã éã«ãèªåæšæž¬ãªã©ã ãšãææ°ã®å€ã ãã«å¯ŸããŠãªã¯ãšã¹ããæãããã¯ããªã®ã§ã mergeMap ãã switchMap ãé©ããŠããã®ã§ã¯ãªãã§ããããïŒ RxJS ã¯å¥¥æ·±ããŠåŒ·åãªã®ã§ããã匷åã ãããã誀ã£ãäœ¿ãæ¹ããããšçãç®ã«éããªãšæã£ãŠããŸãã ã©ãã©ãçè§£ãæ·±ããŠãããŸãããïŒ