├── .gitignore ├── LICENSE ├── README.md ├── SUMMARY.md ├── book.json ├── concepts └── README.md ├── operators ├── README.md ├── combination │ ├── README.md │ ├── combineall.md │ ├── combinelatest.md │ ├── concat.md │ ├── concatall.md │ ├── forkjoin.md │ ├── merge.md │ ├── mergeall.md │ ├── pairwise.md │ ├── race.md │ ├── startwith.md │ ├── withlatestfrom.md │ └── zip.md ├── complete.md ├── conditional │ ├── README.md │ ├── defaultifempty.md │ └── every.md ├── creation │ ├── README.md │ ├── create.md │ ├── empty.md │ ├── from.md │ ├── fromevent.md │ ├── frompromise.md │ ├── interval.md │ ├── of.md │ ├── range.md │ ├── throw.md │ └── timer.md ├── error_handling │ ├── README.md │ ├── catch.md │ ├── retry.md │ └── retrywhen.md ├── filtering │ ├── README.md │ ├── debounce.md │ ├── debouncetime.md │ ├── distinctuntilchanged.md │ ├── filter.md │ ├── first.md │ ├── ignoreelements.md │ ├── last.md │ ├── sample.md │ ├── single.md │ ├── skip.md │ ├── skipuntil.md │ ├── skipwhile.md │ ├── take.md │ ├── takeuntil.md │ ├── takewhile.md │ ├── throttle.md │ └── throttletime.md ├── multicasting │ ├── README.md │ ├── multicast.md │ ├── publish.md │ └── share.md ├── specs │ ├── combination │ │ ├── combineall-spec.ts │ │ ├── combinelatest-spec.ts │ │ ├── concat-spec.ts │ │ ├── concatall-spec.ts │ │ ├── mergeall-spec.ts │ │ └── startwith-spec.ts │ ├── error_handling │ │ └── catch-spec.ts │ ├── filtering │ │ └── first-spec.ts │ └── helpers │ │ ├── marble-testing.ts │ │ └── test-helper.ts ├── transformation │ ├── README.md │ ├── buffer.md │ ├── buffercount.md │ ├── buffertime.md │ ├── buffertoggle.md │ ├── bufferwhen.md │ ├── concatmap.md │ ├── concatmapto.md │ ├── exhaustmap.md │ ├── expand.md │ ├── groupby.md │ ├── map.md │ ├── mapto.md │ ├── mergemap.md │ ├── partition.md │ ├── pluck.md │ ├── scan.md │ ├── switchmap.md │ ├── window.md │ ├── windowcount.md │ ├── windowtime.md │ ├── windowtoggle.md │ └── windowwhen.md └── utility │ ├── README.md │ ├── delay.md │ ├── delaywhen.md │ ├── dematerialize.md │ ├── do.md │ ├── let.md │ └── topromise.md ├── package-lock.json ├── package.json ├── recipes ├── README.md └── smartcounter.md └── wallaby.js /.gitignore: -------------------------------------------------------------------------------- 1 | _book 2 | node_modules 3 | .idea 4 | npm-debug.log 5 | CNAME -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 learn-rxjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn RxJS 2 | 3 | RxJs에 대한 명확한 예제, 설명 그리고 정보가 기재되어있습니다. 4 | 해당 페이지는 [learnrxjs](https://www.learnrxjs.io/)의 내용을 번역한 페이지입니다. 5 | 그외에 추가적인 자료도 계속 추가할 예정입니다. 6 | 7 | ## RxJS 소개 8 | 9 | [RxJS](https://github.com/ReactiveX/rxjs)는 최근 가장 뜨거운 라이브러리 중 하나입니다. 이벤트를 처리하기 위한 강력한 기능을 제공함으로써, 많은 프레임워크, 라이브러리 그리고 유틸리티로 활용되어 제공되고 있습니다. 10 | Rx는 [거의 모든 언어](http://reactivex.io/languages.html)로 활용할 수 있어, 반응성 프로그래밍에 대한 탄탄한 이해력을 가지고 있다면, 조금 더 쉽게 습득이 가능합니다. 11 | 12 | **하지만...** 13 | 14 | RxJS와 리액티브 프로그래밍을 배우는것은 [어렵습니다](https://twitter.com/hoss/status/742643506536153088). 많은 개념, 다양한 API 및 사고 방식의 근본적인 변화가 필요합니다.[(명령형과 선언적 스타일 비교)](http://codenugget.co/2015/03/05/declarative-vs-imperative-programming-web.html) 15 | 이 사이트는 이러한 개념을 접근하기 쉽고, 명확하고 쉽게 찾을 수있는 예제를 작성하는 데 중점을두고 있으며, 웹에서 가장 우수한 RxJS 관련 자료의 참조를 제공합니다. 최종 목표는 [공식문서](http://reactivex.io/rxjs/)와 기존 학습 자료를 보완하여 학습곡선을 낮추어 새롭고 신선한 관점으로 제공하는 것입니다. 16 | Rx를 배우는 것은 어렵지만 배울 가치는 충분히 있습니다! 17 | 18 | ## 이 페이지에서 다루는 내용들 19 | 20 | #### Operators(연산자) 21 | 22 | Operator(연산자)는 observable의 복잡한 비동기 작업을 우아하고 선언적인 해결책을 제공하는 강력한 힘을 가지고 있습니다. 23 | 이 섹션에서는 [JSBin](https://jsbin.com)과 [JSFiddle](https://jsfiddle.net) 양쪽에 모든 ([RxJS 5 연산자](/operators/README.md))들에 명확하고 실행 가능한 예제와 함께 포함되어있습니다. 해당하는 각 operator(연산자)에 대한 추가 정보 및 사용법에 대한 링크도 제공됩니다. 24 | 25 | ##### 연산자 분류 26 | * [Combination](/operators/combination/README.md) 27 | * [Conditional](/operators/conditional/README.md) 28 | * [Creation](/operators/creation/README.md) 29 | * [Error Handling](/operators/error_handling/README.md) 30 | * [Multicasting](/operators/multicasting/README.md) 31 | * [Filtering](/operators/filtering/README.md) 32 | * [Transformation](/operators/transformation/README.md) 33 | * [Utility](/operators/utility/README.md) 34 | 35 | **혹은...** 36 | 37 | [Operator 전체목록(알파벳순)](/operators/complete.md) 38 | 39 | #### Concepts 40 | Observable의 동작원리 같은 기초지식이 없다면, RxJS가 엄청난 '마법'처럼 느껴지기 쉽습니다. 41 | 이 섹션에서는 반응성 프로그래밍과 observable의 주요 개념들을 편안하게 느낄 수 있도록 다루고 있습니다. 42 | 43 | *Coming Soon!* 44 | 45 | #### Recipes 46 | RxJS에 대한 일반적인 사용 사례 및 흥미로운 솔루션등의 예시를 제공합니다. 47 | 48 | [예시 목록](/recipes/README.md) 49 | 50 | ## 입문용 자료들 51 | RxJS와 리액티브 프로그래밍이 처음이십니까? 이 사이트에 있는 내용 말고 다른 훌륭한 글과 동영상들이 도움 될 것 입니다. 여러분들의 학습경험을 시작하세요! 52 | 53 | 54 | #### 읽을자료 목록 55 | * [RxJS Introduction](http://reactivex.io/rxjs/manual/overview.html#introduction) - RxJS 공식 문서 56 | * [The Introduction to Reactive Programming You've Been Missing](https://gist.github.com/staltz/868e7e9bc2a7b8c1f754) - André Staltz 57 | 58 | #### 동영상자료 목록 59 | * [Asynchronous Programming: The End of The Loop](https://egghead.io/courses/mastering-asynchronous-programming-the-end-of-the-loop) - Jafar Husain 60 | * [What is RxJS?](https://egghead.io/lessons/rxjs-what-is-rxjs) - Ben Lesh 61 | * [Creating Observable from Scratch](https://egghead.io/lessons/rxjs-creating-observable-from-scratch) - Ben Lesh 62 | * [Introduction to RxJS Marble Testing](https://egghead.io/lessons/rxjs-introduction-to-rxjs-marble-testing) - Brian Troncone 63 | * [Introduction to Reactive Programming](https://egghead.io/courses/introduction-to-reactive-programming) :dollar: - André Staltz 64 | * [Reactive Programming using Observables](https://www.youtube.com/watch?v=HT7JiiqnYYc&feature=youtu.be) - Jeremy Lund 65 | 66 | #### 실습자료 목록 67 | * [Functional Programming in JavaScript](http://reactivex.io/learnrx/) - Jafar Husain 68 | 69 | #### 학습도구 목록 70 | * [Rx Marbles - Interactive diagrams of Rx Observables](http://rxmarbles.com/) - André Staltz 71 | * [Rx Visualizer - Animated playground for Rx Observables](https://rxviz.com) - Misha Moroshko 72 | 73 | *RxJs 버전 4에 관심이 있으시면 여길 참고하세요. [Denis Stoyanov's](https://github.com/xgrommx) excellent [eBook](https://xgrommx.github.io/rx-book/)!* 74 | 75 | ## 번역목록 76 | * [简体中文](https://rxjs-cn.github.io/learn-rxjs-operators) 77 | * [한국어](https://github.com/tienne/lean-rxjs) 78 | 79 | ### 참조 80 | 이 GitBook에 포함 된 모든 참고 자료는 RxJs와 관련된 무료 및 유료 자료들입니다. 81 | 포함해야한다고 생각되는 내용이나 동영상을 발견 한 경우 상단의 * 페이지 수정 * 링크 메뉴를 클릭하고 Pull를 제출해주세요. 피드백은 항상 환영입니다. -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Summary 2 | 3 | ## Learn RxJS 4 | 5 | * [RxJS 소개](README.md) 6 | * [Operators\(연산자\)](/operators/README.md) 7 | * [Combination](/operators/combination/README.md) 8 | * [combineAll](/operators/combination/combineall.md) 9 | * [combineLatest](/operators/combination/combinelatest.md) 10 | * [concat](/operators/combination/concat.md) 11 | * [concatAll](/operators/combination/concatall.md) 12 | * [forkJoin](/operators/combination/forkjoin.md) 13 | * [merge](/operators/combination/merge.md) 14 | * [mergeAll](/operators/combination/mergeall.md) 15 | * [pairwise](/operators/combination/pairwise.md) 16 | * [race](/operators/combination/race.md) 17 | * [startWith](/operators/combination/startwith.md) 18 | * [withLatestFrom](/operators/combination/withlatestfrom.md) 19 | * [zip](/operators/combination/zip.md) 20 | * [Conditional](/operators/conditional/README.md) 21 | * [defaultIfEmpty](/operators/conditional/defaultifempty.md) 22 | * [every](/operators/conditional/every.md) 23 | * [Creation](/operators/creation/README.md) 24 | * [create](/operators/creation/create.md) 25 | * [empty](/operators/creation/empty.md) 26 | * [from](/operators/creation/from.md) 27 | * [fromEvent](/operators/creation/fromevent.md) 28 | * [fromPromise](/operators/creation/frompromise.md) 29 | * [interval](/operators/creation/interval.md) 30 | * [of](/operators/creation/of.md) 31 | * [range](/operators/creation/range.md) 32 | * [throw](/operators/creation/throw.md) 33 | * [timer](/operators/creation/timer.md) 34 | * [Error Handling](/operators/error_handling/README.md) 35 | * [catch](/operators/error_handling/catch.md) 36 | * [retry](/operators/error_handling/retry.md) 37 | * [retryWhen](/operators/error_handling/retrywhen.md) 38 | * [Multicasting](/operators/multicasting/README.md) 39 | * [cache](/operators/multicasting/cache.md) 40 | * [publish](/operators/multicasting/publish.md) 41 | * [multicast](/operators/multicasting/multicast.md) 42 | * [share](/operators/multicasting/share.md) 43 | * [Filtering](/operators/filtering/README.md) 44 | * [debounce](/operators/filtering/debounce.md) 45 | * [debounceTime](/operators/filtering/debouncetime.md) 46 | * [distinctUntilChanged](/operators/filtering/distinctuntilchanged.md) 47 | * [filter](/operators/filtering/filter.md) 48 | * [first](/operators/filtering/first.md) 49 | * [ignoreElements](/operators/filtering/ignoreelements.md) 50 | * [last](/operators/filtering/last.md) 51 | * [sample](/operators/filtering/sample.md) 52 | * [single](/operators/filtering/single.md) 53 | * [skip](/operators/filtering/skip.md) 54 | * [skipUntil](/operators/filtering/skipuntil.md) 55 | * [skipWhile](/operators/filtering/skipwhile.md) 56 | * [take](/operators/filtering/take.md) 57 | * [takeUntil](/operators/filtering/takeuntil.md) 58 | * [takeWhile](/operators/filtering/takewhile.md) 59 | * [throttle](/operators/filtering/throttle.md) 60 | * [throttleTime](/operators/filtering/throttletime.md) 61 | * [Transformation](/operators/transformation/README.md) 62 | * [buffer](/operators/transformation/buffer.md) 63 | * [bufferCount](/operators/transformation/buffercount.md) 64 | * [bufferTime](/operators/transformation/buffertime.md) 65 | * [bufferToggle](/operators/transformation/buffertoggle.md) 66 | * [bufferWhen](/operators/transformation/bufferwhen.md) 67 | * [concatMap](/operators/transformation/concatmap.md) 68 | * [concatMapTo](/operators/transformation/concatmapto.md) 69 | * [expand](/operators/transformation/expand.md) 70 | * [groupBy](/operators/transformation/groupby.md) 71 | * [map](/operators/transformation/map.md) 72 | * [mapTo](/operators/transformation/mapto.md) 73 | * [mergeMap](/operators/transformation/mergemap.md) 74 | * [partition](/operators/transformation/partition.md) 75 | * [pluck](/operators/transformation/pluck.md) 76 | * [scan](/operators/transformation/scan.md) 77 | * [switchMap](/operators/transformation/switchmap.md) 78 | * [window](/operators/transformation/window.md) 79 | * [windowCount](/operators/transformation/windowcount.md) 80 | * [windowTime](/operators/transformation/windowtime.md) 81 | * [windowToggle](/operators/transformation/windowtoggle.md) 82 | * [windowWhen](/operators/transformation/windowwhen.md) 83 | * [Utility](/operators/utility/README.md) 84 | * [do](/operators/utility/do.md) 85 | * [delay](/operators/utility/delay.md) 86 | * [delayWhen](/operators/utility/delaywhen.md) 87 | * [dematerialize](/operators/utility/dematerialize.md) 88 | * [let](/operators/utility/let.md) 89 | * [toPromise](/operators/utility/topromise.md) 90 | * [Full Listing](/operators/complete.md) 91 | * [Recipes](/recipes/README.md) 92 | * [Smart Counter](/recipes/smartcounter.md) 93 | * [Concepts](/concepts/README.md) 94 | 95 | -------------------------------------------------------------------------------- /book.json: -------------------------------------------------------------------------------- 1 | { 2 | "gitbook": "3.2.3", 3 | "title": "Learn RxJS-ko", 4 | "plugins": [ 5 | "include-codeblock", 6 | "advanced-emoji", 7 | "prism", 8 | "highlight", 9 | "copy-code-button", 10 | "edit-link", 11 | "github", 12 | "github-buttons", 13 | "ga" 14 | ], 15 | "pluginsConfig": { 16 | "edit-link": { 17 | "base": "https://github.com/tienne/learn-rxjs/tree/master", 18 | "label": "페이지 수정" 19 | }, 20 | "github": { 21 | "url": "https://github.com/tienne/learn-rxjs" 22 | }, 23 | "ga": { 24 | "token": "UA-106927575-1" 25 | }, 26 | "github-buttons": { 27 | "repo": "tienne/learn-rxjs", 28 | "types": [ 29 | "star", 30 | "watch" 31 | ], 32 | "size": "small" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /concepts/README.md: -------------------------------------------------------------------------------- 1 | # Concepts 2 | 3 | *추가예정입니다..* -------------------------------------------------------------------------------- /operators/README.md: -------------------------------------------------------------------------------- 1 | # RxJS 5 연산자(Operator) 2 | 3 | RxJS5 연산자(Operator) 대한 설명과 관련 자료 및 실행 가능한 예제가 포함된 전체 목록입니다. 4 | 5 | *[알파벳순으로 정렬된 목록을 보실려면?](complete.md)* 6 | 7 | ### 연산자(Operator) 타입에 따른 목록 8 | * [Combination](combination/README.md) 9 | * [combineAll](combination/combineall.md) 10 | * [combineLatest](combination/combinelatest.md) :star: 11 | * [concat](combination/concat.md) :star: 12 | * [concatAll](combination/concatall.md) 13 | * [forkJoin](combination/forkjoin.md) 14 | * [merge](combination/merge.md) :star: 15 | * [mergeAll](combination/mergeall.md) 16 | * [race](combination/race.md) 17 | * [startWith](combination/startwith.md) :star: 18 | * [withLatestFrom](combination/withlatestfrom.md) :star: 19 | * [zip](combination/zip.md) 20 | * [Conditional](conditional/README.md) 21 | * [defaultIfEmpty](conditional/defaultifempty.md) 22 | * [every](conditional/every.md) 23 | * [Creation](creation/README.md) 24 | * [create](creation/create.md) 25 | * [empty](creation/empty.md) 26 | * [from](creation/from.md) :star: 27 | * [fromEvent](creation/fromevent.md) 28 | * [fromPromise](creation/frompromise.md) :star: 29 | * [interval](creation/interval.md) 30 | * [of](creation/of.md) :star: 31 | * [range](creation/range.md) 32 | * [throw](creation/throw.md) 33 | * [timer](creation/timer.md) 34 | * [Error Handling](error_handling/README.md) 35 | * [catch](error_handling/catch.md) :star: 36 | * [retry](error_handling/retry.md) 37 | * [retryWhen](error_handling/retrywhen.md) 38 | * [Filtering](filtering/README.md) 39 | * [debounce](filtering/debounce.md) 40 | * [debounceTime](filtering/debouncetime.md) :star: 41 | * [distinctUntilChanged](filtering/distinctuntilchanged.md) :star: 42 | * [filter](filtering/filter.md) :star: 43 | * [first](filtering/first.md) 44 | * [ignoreElements](filtering/ignoreelements.md) 45 | * [last](filtering/last.md) 46 | * [sample](filtering/sample.md) 47 | * [single](filtering/single.md) 48 | * [skip](filtering/skip.md) 49 | * [skipUntil](filtering/skipuntil.md) 50 | * [skipWhile](filtering/skipwhile.md) 51 | * [take](filtering/take.md) :star: 52 | * [takeUntil](filtering/takeuntil.md) :star: 53 | * [takeWhile](filtering/takewhile.md) 54 | * [throttle](filtering/throttle.md) 55 | * [throttleTime](filtering/throttletime.md) 56 | * [Multicasting](multicasting/README.md) 57 | * [multicast](multicasting/multicast.md) 58 | * [publish](multicasting/publish.md) 59 | * [share](multicasting/share.md) :star: 60 | * [Transformation](transformation/README.md) 61 | * [buffer](transformation/buffer.md) 62 | * [bufferCount](transformation/buffercount.md) 63 | * [bufferTime](transformation/buffertime.md) :star: 64 | * [bufferToggle](transformation/buffertoggle.md) 65 | * [bufferWhen](transformation/bufferwhen.md) 66 | * [concatMap](transformation/concatmap.md) :star: 67 | * [concatMapTo](transformation/concatmapto.md) 68 | * [expand](transformation/expand.md) 69 | * [exhaustMap](tranformation/exhaustmap.md) 70 | * [groupBy](transformation/groupby.md) 71 | * [map](transformation/map.md) :star: 72 | * [mapTo](transformation/mapto.md) 73 | * [mergeMap](transformation/mergemap.md) :star: 74 | * [partition](transformation/partition.md) 75 | * [pluck](transformation/pluck.md) 76 | * [scan](transformation/scan.md) :star: 77 | * [switchMap](transformation/switchmap.md) :star: 78 | * [window](transformation/window.md) 79 | * [windowCount](transformation/windowcount.md) 80 | * [windowTime](transformation/windowtime.md) 81 | * [windowToggle](transformation/windowtoggle.md) 82 | * [windowWhen](transformation/windowwhen.md) 83 | * [Utility](utility/README.md) 84 | * [do](utility/do.md) :star: 85 | * [delay](utility/delay.md) 86 | * [delayWhen](utility/delaywhen.md) 87 | * [let](utility/let.md) 88 | * [toPromise](utility/topromise.md) 89 | 90 | :star: - *많이 사용되는 연산자(operator)* 91 | 92 | ### 추가 자료목록 93 | * [What Are Operators?](http://reactivex.io/rxjs/manual/overview.html#operators) :newspaper: - Official Docs 94 | * [What Operators Are](https://egghead.io/lessons/rxjs-what-rxjs-operators-are) :video_camera: :dollar: - André Staltz 95 | -------------------------------------------------------------------------------- /operators/combination/README.md: -------------------------------------------------------------------------------- 1 | # Combination Operators(조합 연산자) 2 | 3 | combination Operator(조합 연산자)는 여러개의 Observable를 결합하는 연산자입니다. 4 | 결합된 스트림은 값의 순서, 시간 및 구조가 변경되는게 특징입니다. 5 | 6 | ## 연산자 목록 7 | * [combineAll](combineall.md) 8 | * [combineLatest](combinelatest.md) :star: 9 | * [concat](concat.md) :star: 10 | * [concatAll](concatall.md) 11 | * [forkJoin](forkjoin.md) 12 | * [merge](merge.md) :star: 13 | * [mergeAll](mergeall.md) 14 | * [pairwise](pairwise.md) 15 | * [race](race.md) 16 | * [startWith](startwith.md) :star: 17 | * [withLatestFrom](withlatestfrom.md) :star: 18 | * [zip](zip.md) 19 | 20 | :star: - *많이 사용되는 연산자(operator)* 21 | -------------------------------------------------------------------------------- /operators/combination/combineall.md: -------------------------------------------------------------------------------- 1 | # combineAll 2 | #### 연산자(operator) 정의: `combineAll(project: function): Observable` 3 | 4 | ## Observable의 Observable들이 완료(complate)되면 [combineLatest](combinelatest.md)를 적용하여 Observable의 Observable들을 평평하게 만듭니다. 5 | 6 | ![Image](http://reactivex.io/rxjs/img/combineAll.png) 7 | 8 | ### Examples 9 | 10 | ( [예시 테스트코드](https://github.com/tienne/learn-rxjs/blob/master/operators/specs/combination/combineall-spec.ts) ) 11 | 12 | ##### 예시 1: 각각 일정한 간격의 Observable 맵핑 처리 13 | 14 | ( [jsBin](http://jsbin.com/cokinogime/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/pvj1nbLa/) ) 15 | 16 | ```js 17 | //1초 간격으로 2회 스트림 발생 18 | const source = Rx.Observable.interval(1000).take(2); 19 | //source에서 발생되는 값을 일정간격으로 5회 반복되는 스트림으로 맵핑 20 | const example = source.map(val => Rx.Observable.interval(1000).map(i => `Result (${val}): ${i}`).take(5)); 21 | /* 22 | source에서 발생되는 2회 값들을 각각 내부적으로 1초 간격으로 5회 발생되는 observable로 맵핑되며 23 | combineAll은 combineLatest 방식을 사용하여, 24 | observable의 값이 발생 할 때마다 각각의 마지막 값을 발생시킵니다. 25 | */ 26 | const combined = example.combineAll(); 27 | /* 28 | output: 29 | ["Result (0): 0", "Result (1): 0"] 30 | ["Result (0): 1", "Result (1): 0"] 31 | ["Result (0): 1", "Result (1): 1"] 32 | ["Result (0): 2", "Result (1): 1"] 33 | ["Result (0): 2", "Result (1): 2"] 34 | ["Result (0): 3", "Result (1): 2"] 35 | ["Result (0): 3", "Result (1): 3"] 36 | ["Result (0): 4", "Result (1): 3"] 37 | ["Result (0): 4", "Result (1): 4"] 38 | */ 39 | const subscribe = combined.subscribe(val => console.log(val)); 40 | ``` 41 | 42 | 43 | ### 추가 자료 목록 44 | * [combineAll](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-combineAll) :newspaper: - Official docs 45 | 46 | --- 47 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/combineAll.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/combineAll.ts) 48 | -------------------------------------------------------------------------------- /operators/combination/combinelatest.md: -------------------------------------------------------------------------------- 1 | # combineLatest 2 | #### 연산자(operator) 정의: `combineLatest(observables: ...Observable, project: function): Observable` 3 | 4 | ## 결합시키는 Observable들 중 아무 Observable의 값이 발생될때, 각각 마지막 값으로 넘겨줍니다. 5 | 6 | --- 7 | :bulb: 이 연산자(operator)는 static 또는 Observable의 인스턴스 메서드로도 사용할 수 있습니다! 8 | 9 | :bulb: [combineAll](combineall.md) 연산자는 observable의 observable들이 완료되었을때 combineLatest를 이용하여 결합됩니다. 10 | 11 | --- 12 | 13 | ![](http://reactivex.io/rxjs/img/combineLatest.png) 14 | 15 | ### Examples 16 | 17 | ( [예시 테스트코드](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/combinelatest-spec.ts) ) 18 | 19 | ##### 예시 1: 일정 간격으로 발생되는 3개의 observable들을 결합 20 | ( [jsBin](http://jsbin.com/zupiqozaro/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/mygy9j86/) ) 21 | 22 | ```js 23 | //timerOne은 1초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 24 | const timerOne = Rx.Observable.timer(1000, 4000); 25 | // timerTwo는 2초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 26 | const timerTwo = Rx.Observable.timer(2000, 4000); 27 | //timerThree는 3초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 28 | const timerThree = Rx.Observable.timer(3000, 4000); 29 | 30 | //하나의 타이머가 작동하면 각 타이머의 최신 값을 배열로 발생시킵니다. 31 | const combined = Rx.Observable 32 | .combineLatest( 33 | timerOne, 34 | timerTwo, 35 | timerThree 36 | ); 37 | 38 | const subscribe = combined.subscribe(latestValues => { 39 | //타이머 one, two, three에 해당하는 값 변수 선언 40 | const [timerValOne, timerValTwo, timerValThree] = latestValues; 41 | /* 42 | Example: 43 | timerOne first tick: 'Timer One Latest: 1, Timer Two Latest:0, Timer Three Latest: 0 44 | timerTwo first tick: 'Timer One Latest: 1, Timer Two Latest:1, Timer Three Latest: 0 45 | timerThree first tick: 'Timer One Latest: 1, Timer Two Latest:1, Timer Three Latest: 1 46 | */ 47 | console.log( 48 | `Timer One Latest: ${timerValOne}, 49 | Timer Two Latest: ${timerValTwo}, 50 | Timer Three Latest: ${timerValThree}` 51 | ); 52 | }); 53 | ``` 54 | 55 | ##### 예시 2: projection function를 같이 넘긴 combineLatest 연산자(operator) 사용 56 | 57 | ( [jsBin](http://jsbin.com/codotapula/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/uehasmb6/) ) 58 | 59 | ```js 60 | //timerOne은 1초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 61 | const timerOne = Rx.Observable.timer(1000, 4000); 62 | // timerTwo는 2초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 63 | const timerTwo = Rx.Observable.timer(2000, 4000); 64 | //timerThree는 3초에 첫 번째 값을 내고 4초마다 한 번씩 값을 발생시킵니다. 65 | const timerThree = Rx.Observable.timer(3000, 4000); 66 | 67 | //combineLatest 연산자(operator)는 projection 함수 넘겨줄 경우 스트림 발생시마다 projection 함수를 실행하여 값을 발생시킵니다. 68 | const combinedProject = Rx.Observable 69 | .combineLatest( 70 | timerOne, 71 | timerTwo, 72 | timerThree, 73 | (one, two, three) => { 74 | return `Timer One (Proj) Latest: ${one}, 75 | Timer Two (Proj) Latest: ${two}, 76 | Timer Three (Proj) Latest: ${three}` 77 | } 78 | ); 79 | //발생된 값 구독하여 확인 80 | const subscribe = combinedProject.subscribe(latestValuesProject => console.log(latestValuesProject)); 81 | ``` 82 | 83 | ##### 예시 3: 2개의 버튼 이벤트들을 결합 84 | 85 | ( [jsBin](http://jsbin.com/hiyetucite/edit?html,js,output) | [jsFiddle](https://jsfiddle.net/btroncone/9rsf6t9v/1/) ) 86 | 87 | ```js 88 | // html를 설정하는 함수 89 | const setHtml = id => val => document.getElementById(id).innerHTML = val; 90 | 91 | function(id) { 92 | return function(val) { 93 | document.getElementById(id).innerHTML = val; 94 | } 95 | } 96 | const addOneClick$ = id => Rx.Observable 97 | .fromEvent(document.getElementById(id), 'click') 98 | // 매 클릭을 1로 변경(맵핑) 99 | .mapTo(1) 100 | .startWith(0) 101 | // 클릭한것들을 계속 누적(reduce) 102 | .scan((acc, curr) => acc + curr) 103 | // 클릭횟수를 HTML에 적용시킵니다. 104 | .do(setHtml(`${id}Total`)) 105 | 106 | 107 | const combineTotal$ = Rx.Observable 108 | .combineLatest( 109 | addOneClick$('red'), 110 | addOneClick$('black') 111 | ) 112 | .map(([val1, val2]) => val1 + val2) 113 | .subscribe(setHtml('total')); 114 | ``` 115 | ###### HTML 116 | ```html 117 |
118 | 119 | 120 |
121 |
122 |
123 |
124 | ``` 125 | 126 | ### 추가 자료 목록 127 | * [combineLatest](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-combineLatest) :newspaper: - Official docs 128 | * [Combining streams with combineLatest](https://egghead.io/lessons/rxjs-combining-streams-with-combinelatest?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 129 | * [Combination operator: combineLatest](https://egghead.io/lessons/rxjs-combination-operator-combinelatest?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 130 | 131 | --- 132 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/combineLatest.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/combineLatest.ts) 133 | -------------------------------------------------------------------------------- /operators/combination/concat.md: -------------------------------------------------------------------------------- 1 | # concat 2 | #### 연산자(operator) 정의: `concat(observables: ...*): Observable` 3 | 4 | ## Observable를 순차적으로 구독완료하며 값을 발생시킵니다. 5 | 6 | --- 7 | :bulb: concat을 ATM기기 앞에 서있는 줄처럼 생각하시면 됩니다. 다음 구독 실행은 이전 Observable이 완료되기 전까지 실행이 불가능합니다! 8 | 9 | :bulb: 이 연산자(operator)는 static 또는 Observable의 인스턴스 메서드로도 사용할 수 있습니다! 10 | 11 | :bulb: 실행 순서가 상관이 없다면 [merge](merge.md) 연산자를 확인해보세요. 12 | 13 | --- 14 | 15 | ![](http://reactivex.io/rxjs/img/concat.png) 16 | 17 | ### Examples 18 | 19 | ( [예시 테스트코드](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/concat-spec.ts) ) 20 | 21 | ##### Example 1: 기본적인 2개의 Observable 결합 22 | 23 | ( [jsBin](http://jsbin.com/gegubutele/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/rxwnr3hh/) ) 24 | 25 | ```js 26 | //1,2,3 값 발생 27 | const sourceOne = Rx.Observable.of(1,2,3); 28 | //4,5,6 값 발생 29 | const sourceTwo = Rx.Observable.of(4,5,6); 30 | //sourceOne 값 발생하고, 완료가 되었을때, sourceTwo를 이어서 구독합니다. 31 | const example = sourceOne.concat(sourceTwo); 32 | //output: 1,2,3,4,5,6 33 | const subscribe = example.subscribe(val => console.log('Example: Basic concat:', val)); 34 | ``` 35 | 36 | ##### Example 2: concat의 static 메서드로 활용 37 | 38 | ( [jsBin](http://jsbin.com/xihagewune/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5qdtvhu8/) ) 39 | 40 | ```js 41 | //1,2,3 값 발생 42 | const sourceOne = Rx.Observable.of(1,2,3); 43 | //4,5,6 값 발생 44 | const sourceTwo = Rx.Observable.of(4,5,6); 45 | 46 | //static 메서드로 사용 47 | const example = Rx.Observable.concat( 48 | sourceOne, 49 | sourceTwo 50 | ); 51 | //output: 1,2,3,4,5,6 52 | const subscribe = example.subscribe(val => console.log('Example: static', val)); 53 | ``` 54 | 55 | ##### Example 3: 지연처리가 들어간 Observable과의 결합 56 | 57 | ( [jsBin](http://jsbin.com/nezonosubi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/L2s49msx/) ) 58 | 59 | ```js 60 | //1,2,3 값 발생 61 | const sourceOne = Rx.Observable.of(1,2,3); 62 | //4,5,6 값 발생 63 | const sourceTwo = Rx.Observable.of(4,5,6); 64 | 65 | //값 발생을 3초 지연 시킴 66 | const sourceThree = sourceOne.delay(3000); 67 | //sourceTwo는 sourceOne이 구독 완료되기전까지 기다린다. 68 | const example = sourceThree.concat(sourceTwo); 69 | //output: 1,2,3,4,5,6 70 | const subscribe = example.subscribe(val => console.log('Example: Delayed source one:', val)); 71 | ``` 72 | 73 | ##### Example 4: 완료되지 않은 Observable과의 결합 74 | 75 | ( [jsBin](http://jsbin.com/vixajoxaze/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/4bhtb81u/) ) 76 | 77 | ```js 78 | //두번째로 실행될 Rx.Observable.of('This','Never','Runs')는 앞에 Observable이 완료되지 않기때문에 실행되지 않습니다. 79 | const source = Rx.Observable 80 | .concat( 81 | Rx.Observable.interval(1000), 82 | Rx.Observable.of('This','Never','Runs') 83 | ) 84 | //outputs: 1,2,3,4.... 85 | const subscribe = source.subscribe(val => console.log('Example: Source never completes, second observable never runs:', val)); 86 | ``` 87 | 88 | 89 | ### 추가자료들 90 | * [concat](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concat) :newspaper: - Official docs 91 | * [Combination operator: concat, startWith](https://egghead.io/lessons/rxjs-combination-operators-concat-startwith?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 92 | 93 | --- 94 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/concat.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/concat.ts) 95 | -------------------------------------------------------------------------------- /operators/combination/concatall.md: -------------------------------------------------------------------------------- 1 | # concatAll 2 | #### 연산자(operator) 정의: `concatAll(): Observable` 3 | 4 | ## observable의 observable를 결합하고 이전 Observable이 완료되면 그 다음 Observable의 구독이 실행됩니다. 5 | 6 | --- 7 | :warning: Be wary of [backpressure](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md) when the source emits at a faster pace than inner observables complete! 8 | 9 | :bulb: In many cases you can use [concatMap](../transformation/concatmap.md) as a single operator instead! 10 | 11 | --- 12 | 13 | ![](http://reactivex.io/rxjs/img/concatAll.png) 14 | 15 | ### Examples 16 | 17 | ( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/concatall-spec.ts) ) 18 | 19 | ##### Example 1: concatAll with observable 20 | 21 | ( [jsBin](http://jsbin.com/nakinenuva/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8dfuf2y6/) ) 22 | 23 | ```js 24 | //emit a value every 2 seconds 25 | const source = Rx.Observable.interval(2000); 26 | const example = source 27 | //for demonstration, add 10 to and return as observable 28 | .map(val => Rx.Observable.of(val + 10)) 29 | //merge values from inner observable 30 | .concatAll(); 31 | //output: 'Example with Basic Observable 10', 'Example with Basic Observable 11'... 32 | const subscribe = example.subscribe(val => console.log('Example with Basic Observable:', val)); 33 | ``` 34 | 35 | ##### Example 2: concatAll with promise 36 | 37 | ( [jsBin](http://jsbin.com/bekegeyopu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/w7kp7qLs/) ) 38 | 39 | ```js 40 | //create and resolve basic promise 41 | const samplePromise = val => new Promise(resolve => resolve(val)); 42 | //emit a value every 2 seconds 43 | const source = Rx.Observable.interval(2000); 44 | 45 | const example = source 46 | .map(val => samplePromise(val)) 47 | //merge values from resolved promise 48 | .concatAll(); 49 | //output: 'Example with Promise 0', 'Example with Promise 1'... 50 | const subscribe = example.subscribe(val => console.log('Example with Promise:', val)); 51 | ``` 52 | 53 | ##### Example 3: Delay while inner observables complete 54 | 55 | ( [jsBin](http://jsbin.com/pojolatile/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8230ucbg/) ) 56 | 57 | ```js 58 | const obs1 = Rx.Observable.interval(1000).take(5); 59 | const obs2 = Rx.Observable.interval(500).take(2); 60 | const obs3 = Rx.Observable.interval(2000).take(1); 61 | //emit three observables 62 | const source = Rx.Observable.of(obs1, obs2, obs3); 63 | //subscribe to each inner observable in order when previous completes 64 | const example = source.concatAll(); 65 | /* 66 | output: 0,1,2,3,4,0,1,0 67 | How it works... 68 | Subscribes to each inner observable and emit values, when complete subscribe to next 69 | obs1: 0,1,2,3,4 (complete) 70 | obs2: 0,1 (complete) 71 | obs3: 0 (complete) 72 | */ 73 | 74 | const subscribe = example.subscribe(val => console.log(val)); 75 | ``` 76 | 77 | ### 추가자료 목록 78 | * [concatAll](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concatAll) :newspaper: - Official docs 79 | * [Flatten a higher order observable with concatAll in RxJS](https://egghead.io/lessons/rxjs-flatten-a-higher-order-observable-with-concatall-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 80 | 81 | --- 82 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatAll.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatAll.ts) 83 | -------------------------------------------------------------------------------- /operators/combination/forkjoin.md: -------------------------------------------------------------------------------- 1 | # forkJoin 2 | #### 연산자(operator) 정의: `forkJoin(...args, selector : function): Observable` 3 | 4 | ## When all observables complete emit the last value from each. 5 | 6 | --- 7 | :bulb: If you want corresponding emissions from multiple observables as they occur, try [zip](zip.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Making variable number of requests 14 | 15 | ( [jsBin](http://jsbin.com/taziyomusa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5fj77920/) ) 16 | 17 | ```js 18 | const myPromise = val => new Promise(resolve => setTimeout(() => resolve(`Promise Resolved: ${val}`), 5000)) 19 | 20 | /* 21 | when all observables complete, give the last 22 | emitted value from each as an array 23 | */ 24 | const example = Rx.Observable.forkJoin( 25 | //emit 'Hello' immediately 26 | Rx.Observable.of('Hello'), 27 | //emit 'World' after 1 second 28 | Rx.Observable.of('World').delay(1000), 29 | //emit 0 after 1 second 30 | Rx.Observable.interval(1000).take(1), 31 | //emit 0...1 in 1 second interval 32 | Rx.Observable.interval(1000).take(2), 33 | //promise that resolves to 'Promise Resolved' after 5 seconds 34 | myPromise('RESULT') 35 | ); 36 | //output: ["Hello", "World", 0, 1, "Promise Resolved: RESULT"] 37 | const subscribe = example.subscribe(val => console.log(val)); 38 | 39 | //make 5 requests 40 | const queue = Rx.Observable.of([1,2,3,4,5]); 41 | //emit array of all 5 results 42 | const exampleTwo = queue 43 | .mergeMap(q => Rx.Observable.forkJoin(...q.map(myPromise))); 44 | /* 45 | output: 46 | [ 47 | "Promise Resolved: 1", 48 | "Promise Resolved: 2", 49 | "Promise Resolved: 3", 50 | "Promise Resolved: 4", 51 | "Promise Resolved: 5" 52 | ] 53 | */ 54 | const subscribeTwo = exampleTwo.subscribe(val => console.log(val)); 55 | ``` 56 | 57 | 58 | ### Additional Resources 59 | * [forkJoin](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-forkJoin) :newspaper: - Official docs 60 | 61 | --- 62 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/ForkJoinObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/ForkJoinObservable.ts) 63 | -------------------------------------------------------------------------------- /operators/combination/merge.md: -------------------------------------------------------------------------------- 1 | # merge 2 | #### 연산자(operator) 정의: `merge(input: Observable): Observable` 3 | 4 | ## Turn multiple observables into a single observable. 5 | 6 | --- 7 | :bulb: This operator can be used as either a static or instance method! 8 | 9 | :bulb: If order not throughput is a primary concern, try [concat](concat.md) instead! 10 | 11 | --- 12 | 13 | ### Examples 14 | 15 | ##### Example 1: merging multiple observables, static method 16 | 17 | ( [jsBin](http://jsbin.com/conufujapi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qvq9dscu/) ) 18 | 19 | ```js 20 | //emit every 2.5 seconds 21 | const first = Rx.Observable.interval(2500); 22 | //emit every 2 seconds 23 | const second = Rx.Observable.interval(2000); 24 | //emit every 1.5 seconds 25 | const third = Rx.Observable.interval(1500); 26 | //emit every 1 second 27 | const fourth = Rx.Observable.interval(1000); 28 | 29 | //emit outputs from one observable 30 | const example = Rx.Observable.merge( 31 | first.mapTo('FIRST!'), 32 | second.mapTo('SECOND!'), 33 | third.mapTo('THIRD'), 34 | fourth.mapTo('FOURTH') 35 | ); 36 | //output: "FOURTH", "THIRD", "SECOND!", "FOURTH", "FIRST!", "THIRD", "FOURTH" 37 | const subscribe = example.subscribe(val => console.log(val)); 38 | ``` 39 | 40 | ##### Example 2: merge 2 observables, instance method 41 | 42 | ( [jsBin](http://jsbin.com/wuwujokaqu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/me5ofcr0/) ) 43 | 44 | ```js 45 | //emit every 2.5 seconds 46 | const first = Rx.Observable.interval(2500); 47 | //emit every 1 second 48 | const second = Rx.Observable.interval(1000); 49 | //used as instance method 50 | const example = first.merge(second); 51 | //output: 0,1,0,2.... 52 | const subscribe = example.subscribe(val => console.log(val)); 53 | ``` 54 | 55 | 56 | ### Additional Resources 57 | * [merge](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-merge) :newspaper: - Official docs 58 | * [Handling multiple streams with merge](https://egghead.io/lessons/rxjs-handling-multiple-streams-with-merge?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 59 | * [Sharing network requests with merge](https://egghead.io/lessons/rxjs-reactive-programming-sharing-network-requests-with-rxjs-merge?course=introduction-to-reactive-programming) :video_camera: :dollar: - André Staltz 60 | * [Combination operator: merge](https://egghead.io/lessons/rxjs-combination-operator-merge?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 61 | 62 | --- 63 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/merge.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/merge.ts) 64 | -------------------------------------------------------------------------------- /operators/combination/mergeall.md: -------------------------------------------------------------------------------- 1 | # mergeAll 2 | #### 연산자(operator) 정의: `mergeAll(concurrent: number): Observable` 3 | 4 | ## Collect and subscribe to all observables. 5 | 6 | --- 7 | :bulb: In many cases you can use [mergeMap](../transformation/mergemap.md) as a single operator instead! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/mergeall-spec.ts) ) 14 | 15 | ##### Example 1: mergeAll with promises 16 | 17 | ( [jsBin](http://jsbin.com/worecuhiba/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/0sc4nsxa/) ) 18 | 19 | ```js 20 | const myPromise = val => new Promise(resolve => setTimeout(() => resolve(`Result: ${val}`), 2000)) 21 | //emit 1,2,3 22 | const source = Rx.Observable.of(1,2,3); 23 | 24 | const example = source 25 | //map each value to promise 26 | .map(val => myPromise(val)) 27 | //emit result from source 28 | .mergeAll(); 29 | 30 | /* 31 | output: 32 | "Result: 1" 33 | "Result: 2" 34 | "Result: 3" 35 | */ 36 | const subscribe = example.subscribe(val => console.log(val)); 37 | ``` 38 | 39 | ##### Example 2: mergeAll with *concurrent* parameter 40 | 41 | ( [jsFiddle](https://jsfiddle.net/zra3zxhs/) ) 42 | 43 | ```js 44 | console.clear(); 45 | 46 | const interval = Rx.Observable.interval(500).take(5); 47 | 48 | /* 49 | interval is emitting a value every 0.5s. This value is then being mapped to interval that 50 | is delayed for 1.0s. The mergeAll operator takes an optional argument that determines how 51 | many inner observables to subscribe to at a time. The rest of the observables are stored 52 | in a backlog waiting to be subscribe. 53 | */ 54 | const example = interval 55 | .map(val => interval.delay(1000).take(3)) 56 | .mergeAll(2) 57 | .subscribe(val => console.log(val)); 58 | /* 59 | The subscription is completed once the operator emits all values. 60 | */ 61 | ``` 62 | 63 | 64 | ### Additional Resources 65 | * [mergeAll](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mergeAll) :newspaper: - Official docs 66 | * [Flatten a higher order observable with mergeAll in RxJS](https://egghead.io/lessons/rxjs-flatten-a-higher-order-observable-with-mergeall-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 67 | 68 | --- 69 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/mergeAll.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/mergeAll.ts) 70 | -------------------------------------------------------------------------------- /operators/combination/pairwise.md: -------------------------------------------------------------------------------- 1 | # pairwise 2 | #### 연산자(operator) 정의: `pairwise(): Observable` 3 | 4 | ## Emit the previous and current values as an array. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: 9 | 10 | ( [jsBin](http://jsbin.com/keteyahido/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8va47bq3/) ) 11 | 12 | ```js 13 | var interval = Rx.Observable.interval(1000); 14 | 15 | //Returns: [0,1], [1,2], [2,3], [3,4], [4,5] 16 | interval.pairwise() 17 | .take(5) 18 | .subscribe(console.log); 19 | ``` 20 | 21 | ### Additional Resources 22 | * [pairwise](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-pairwise) :newspaper: - Official docs 23 | 24 | --- 25 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/pairwise.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/pairwise.ts) 26 | -------------------------------------------------------------------------------- /operators/combination/race.md: -------------------------------------------------------------------------------- 1 | # race 2 | #### 연산자(operator) 정의: `race(): Observable` 3 | 4 | ## The observable to emit first is used. 5 | 6 | 7 | ### Examples 8 | 9 | ##### Example 1: race with 4 observables 10 | 11 | ( [jsBin](http://jsbin.com/goqiwobeno/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8jcmb1ec/) ) 12 | 13 | ```js 14 | //take the first observable to emit 15 | const example = Rx.Observable.race( 16 | //emit every 1.5s 17 | Rx.Observable.interval(1500), 18 | //emit every 1s 19 | Rx.Observable.interval(1000).mapTo('1s won!'), 20 | //emit every 2s 21 | Rx.Observable.interval(2000), 22 | //emit every 2.5s 23 | Rx.Observable.interval(2500) 24 | ); 25 | //output: "1s won!"..."1s won!"...etc 26 | const subscribe = example.subscribe(val => console.log(val)); 27 | ``` 28 | 29 | ##### Example 2: race with an error 30 | 31 | ( [jsFiddle](https://jsfiddle.net/gbeL4t55/2/) ) 32 | 33 | ```js 34 | console.clear(); 35 | 36 | //Throws an error and ignore the rest of the observables. 37 | const first = Rx.Observable.of('first').delay(100).map(() => {throw 'error'}); 38 | const second = Rx.Observable.of('second').delay(200); 39 | const third = Rx.Observable.of('third').delay(300); 40 | 41 | const race = Rx.Observable.race(first, second, third) 42 | .subscribe(val => console.log(val)); 43 | ``` 44 | 45 | ### Additional Resources 46 | * [race](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-race) :newspaper: - Official docs 47 | 48 | --- 49 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/race.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/race.ts) 50 | -------------------------------------------------------------------------------- /operators/combination/startwith.md: -------------------------------------------------------------------------------- 1 | # startWith 2 | #### 연산자(operator) 정의: `startWith(an: Values): Observable` 3 | 4 | ## Emit given value first. 5 | 6 | --- 7 | :bulb: A [BehaviorSubject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/behaviorsubject.md) can also start with an initial value! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/combination/startwith-spec.ts) ) 14 | 15 | ##### Example 1: startWith on number sequence 16 | 17 | ( [jsBin](http://jsbin.com/lezuravizu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/e8dn3ggp/) ) 18 | 19 | ```js 20 | //emit (1,2,3) 21 | const source = Rx.Observable.of(1,2,3); 22 | //start with 0 23 | const example = source.startWith(0); 24 | //output: 0,1,2,3 25 | const subscribe = example.subscribe(val => console.log(val)); 26 | ``` 27 | 28 | ##### Example 2: startWith for initial scan value 29 | 30 | ( [jsBin](http://jsbin.com/gemevuzoha/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/54r3g83e/) ) 31 | 32 | ```js 33 | //emit ('World!', 'Goodbye', 'World!') 34 | const source = Rx.Observable.of('World!', 'Goodbye', 'World!'); 35 | //start with 'Hello', concat current string to previous 36 | const example = source 37 | .startWith('Hello') 38 | .scan((acc, curr) => `${acc} ${curr}`); 39 | /* 40 | output: 41 | "Hello" 42 | "Hello World!" 43 | "Hello World! Goodbye" 44 | "Hello World! Goodbye World!" 45 | */ 46 | const subscribe = example.subscribe(val => console.log(val)); 47 | ``` 48 | 49 | ##### Example 3: startWith multiple values 50 | 51 | ( [jsBin](http://jsbin.com/cumupemuxa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ckcyj3ms/) ) 52 | 53 | ```js 54 | //emit values in sequence every 1s 55 | const source = Rx.Observable.interval(1000); 56 | //start with -3, -2, -1 57 | const example = source.startWith(-3, -2, -1); 58 | //output: -3, -2, -1, 0, 1, 2.... 59 | const subscribe = example.subscribe(val => console.log(val)); 60 | ``` 61 | 62 | ### Related Recipes 63 | * [Smart Counter](../../recipes/smartcounter.md) 64 | 65 | ### Additional Resources 66 | * [startWith](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-startWith) :newspaper: - Official docs 67 | * [Displaying initial data with startWith](https://egghead.io/lessons/rxjs-displaying-initial-data-with-startwith?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 68 | * [Clear data while loading with startWith](https://egghead.io/lessons/rxjs-reactive-programming-clear-data-while-loading-with-rxjs-startwith?course=introduction-to-reactive-programming) :video_camera: :dollar: - André Staltz 69 | * [Combination operator: concat, startWith](https://egghead.io/lessons/rxjs-combination-operators-concat-startwith?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 70 | 71 | 72 | --- 73 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/startWith.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/startWith.ts) 74 | -------------------------------------------------------------------------------- /operators/combination/withlatestfrom.md: -------------------------------------------------------------------------------- 1 | # withLatestFrom 2 | #### 연산자(operator) 정의: `withLatestFrom(other: Observable, project: Function): Observable` 3 | 4 | ## Also provide the last value from another observable. 5 | 6 | --- 7 | :bulb: If you want the last emission any time a variable number of observables emits, try [combinelatest](combinelatest.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Latest value from quicker second source 14 | 15 | ( [jsBin](http://jsbin.com/fitekeseru/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/9c3pfgpk/) ) 16 | 17 | ```js 18 | //emit every 5s 19 | const source = Rx.Observable.interval(5000); 20 | //emit every 1s 21 | const secondSource = Rx.Observable.interval(1000); 22 | const example = source 23 | .withLatestFrom(secondSource) 24 | .map(([first, second]) => { 25 | return `First Source (5s): ${first} Second Source (1s): ${second}`; 26 | }); 27 | /* 28 | "First Source (5s): 0 Second Source (1s): 4" 29 | "First Source (5s): 1 Second Source (1s): 9" 30 | "First Source (5s): 2 Second Source (1s): 14" 31 | ... 32 | */ 33 | const subscribe = example.subscribe(val => console.log(val)); 34 | ``` 35 | 36 | ##### Example 2: Slower second source 37 | 38 | ( [jsBin](http://jsbin.com/vujekucuxa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/bywLL579/) ) 39 | 40 | ```js 41 | //emit every 5s 42 | const source = Rx.Observable.interval(5000); 43 | //emit every 1s 44 | const secondSource = Rx.Observable.interval(1000); 45 | //withLatestFrom slower than source 46 | const example = secondSource 47 | //both sources must emit at least 1 value (5s) before emitting 48 | .withLatestFrom(source) 49 | .map(([first, second]) => { 50 | return `Source (1s): ${first} Latest From (5s): ${second}`; 51 | }); 52 | /* 53 | "Source (1s): 4 Latest From (5s): 0" 54 | "Source (1s): 5 Latest From (5s): 0" 55 | "Source (1s): 6 Latest From (5s): 0" 56 | ... 57 | */ 58 | const subscribe = example.subscribe(val => console.log(val)); 59 | ``` 60 | 61 | 62 | ### Additional Resources 63 | * [withLatestFrom](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-withLatestFrom) :newspaper: - Official docs 64 | * [Combination operator: withLatestFrom](https://egghead.io/lessons/rxjs-combination-operator-withlatestfrom?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 65 | 66 | --- 67 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/withLatestFrom.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/withLatestFrom.ts) 68 | -------------------------------------------------------------------------------- /operators/combination/zip.md: -------------------------------------------------------------------------------- 1 | # zip 2 | #### 연산자(operator) 정의: `zip(observables: *): Observable` 3 | 4 | ### Description 5 | 6 | ###### TL;DR: After all observables emit, emit values as an array 7 | 8 | The **zip** operator will subscribe to all inner observables, waiting for each to emit a value. Once this occurs, all values with the corresponding index will be emitted. This will continue until at least one inner observable completes. 9 | 10 | --- 11 | :bulb: Combined with [interval](../creation/interval) or [timer](../creation/timer.md), zip can be used to time output from another source! 12 | 13 | --- 14 | 15 | ### Examples 16 | 17 | ##### Example 1: zip multiple observables emitting at alternate intervals 18 | 19 | ( [jsBin](http://jsbin.com/lireyisira/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ton462sg/) ) 20 | 21 | ```js 22 | const sourceOne = Rx.Observable.of('Hello'); 23 | const sourceTwo = Rx.Observable.of('World!'); 24 | const sourceThree = Rx.Observable.of('Goodbye'); 25 | const sourceFour = Rx.Observable.of('World!'); 26 | //wait until all observables have emitted a value then emit all as an array 27 | const example = Rx.Observable 28 | .zip( 29 | sourceOne, 30 | sourceTwo.delay(1000), 31 | sourceThree.delay(2000), 32 | sourceFour.delay(3000) 33 | ); 34 | //output: ["Hello", "World!", "Goodbye", "World!"] 35 | const subscribe = example.subscribe(val => console.log(val)); 36 | ``` 37 | 38 | ##### Example 2: zip when 1 observable completes 39 | 40 | ( [jsBin](http://jsbin.com/fisitatesa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/oamyk3xr/) ) 41 | 42 | ```js 43 | //emit every 1s 44 | const interval = Rx.Observable.interval(1000); 45 | //when one observable completes no more values will be emitted 46 | const example = Rx.Observable 47 | .zip( 48 | interval, 49 | interval.take(2) 50 | ); 51 | //output: [0,0]...[1,1] 52 | const subscribe = example.subscribe(val => console.log(val)); 53 | ``` 54 | 55 | 56 | ### Additional Resources 57 | * [zip](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-zip) :newspaper: - Official docs 58 | * [Combination operator: zip](https://egghead.io/lessons/rxjs-combination-operator-zip?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 59 | 60 | --- 61 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/zip.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/zip.ts) 62 | -------------------------------------------------------------------------------- /operators/complete.md: -------------------------------------------------------------------------------- 1 | # RxJS 5 연산자(Operator) 2 | 3 | RxJS5 연산자(Operator) 대한 설명과 관련 자료 및 실행 가능한 예제가 포함된 전체 목록입니다. 4 | 5 | *[연산자 종류별로 정리된 목록을 보실려면?](README.md)* 6 | 7 | ### 연산자(Operator) 알파벳순으로 정렬된 목록 8 | 9 | * [buffer](transformation/buffer.md) 10 | * [bufferCount](transformation/buffercount.md) 11 | * [bufferTime](transformation/buffertime.md) :star: 12 | * [bufferToggle](transformation/buffertoggle.md) 13 | * [bufferWhen](transformation/bufferwhen.md) 14 | * [catch](error_handling/catch.md) :star: 15 | * [combineAll](combination/combineall.md) 16 | * [combineLatest](combination/combinelatest.md) :star: 17 | * [concat](combination/concat.md) :star: 18 | * [concatAll](combination/concatall.md) 19 | * [concatMap](transformation/concatmap.md) :star: 20 | * [concatMapTo](transformation/concatmapto.md) 21 | * [create](creation/create.md) 22 | * [debounce](filtering/debounce.md) 23 | * [debounceTime](filtering/debouncetime.md) :star: 24 | * [defaultIfEmpty](conditional/defaultifempty.md) 25 | * [distinctUntilChanged](filtering/distinctuntilchanged.md) :star: 26 | * [delay](utility/delay.md) 27 | * [delayWhen](utility/delaywhen.md) 28 | * [do](utility/do.md) :star: 29 | * [every](conditional/every.md) 30 | * [empty](creation/empty.md) 31 | * [expand](transformation/expand.md) 32 | * [exhaustMap](tranformation/exhaustmap.md) 33 | * [filter](filtering/filter.md) :star: 34 | * [first](filtering/first.md) 35 | * [forkJoin](combination/forkjoin.md) 36 | * [from](creation/from.md) :star: 37 | * [fromEvent](creation/fromevent.md) 38 | * [fromPromise](creation/frompromise.md) :star: 39 | * [groupBy](transformation/groupby.md) 40 | * [ignoreElements](filtering/ignoreelements.md) 41 | * [interval](creation/interval.md) 42 | * [last](filtering/last.md) 43 | * [let](utility/let.md) 44 | * [map](transformation/map.md) :star: 45 | * [mapTo](transformation/mapto.md) 46 | * [merge](combination/merge.md) :star: 47 | * [mergeAll](combination/mergeall.md) 48 | * [mergeMap](transformation/mergemap.md) :star: 49 | * [multicast](multicasting/multicast.md) 50 | * [of](creation/of.md) :star: 51 | * [partition](transformation/partition.md) 52 | * [pluck](transformation/pluck.md) 53 | * [publish](multicasting/publish.md) 54 | * [race](combination/race.md) 55 | * [range](creation/range.md) 56 | * [retry](error_handling/retry.md) 57 | * [retryWhen](error_handling/retrywhen.md) 58 | * [sample](filtering/sample.md) 59 | * [share](multicasting/share.md) :star: 60 | * [single](filtering/single.md) 61 | * [skip](filtering/skip.md) 62 | * [skipUntil](filtering/skipuntil.md) 63 | * [skipWhile](filtering/skipwhile.md) 64 | * [startWith](combination/startwith.md) :star: 65 | * [take](filtering/take.md) :star: 66 | * [takeUntil](filtering/takeuntil.md) :star: 67 | * [takeWhile](filtering/takewhile.md) 68 | * [throttle](filtering/throttle.md) 69 | * [throttleTime](filtering/throttletime.md) 70 | * [throw](creation/throw.md) 71 | * [timer](creation/timer.md) 72 | * [toPromise](utility/topromise.md) 73 | * [scan](transformation/scan.md) :star: 74 | * [switchMap](transformation/switchmap.md) :star: 75 | * [window](transformation/window.md) 76 | * [windowCount](transformation/windowcount.md) 77 | * [windowTime](transformation/windowtime.md) 78 | * [windowToggle](transformation/windowtoggle.md) 79 | * [windowWhen](transformation/windowwhen.md) 80 | * [withLatestFrom](combination/withlatestfrom.md) :star: 81 | * [zip](combination/zip.md) 82 | 83 | :star: - *많이 사용되는 연산자(operator)* 84 | 85 | ### 추가 자료목록 86 | * [What Are Operators?](http://reactivex.io/rxjs/manual/overview.html#operators) :newspaper: - Official Docs 87 | * [What Operators Are](https://egghead.io/lessons/rxjs-what-rxjs-operators-are) :video_camera: :dollar: - André Staltz 88 | -------------------------------------------------------------------------------- /operators/conditional/README.md: -------------------------------------------------------------------------------- 1 | # Conditional Operators 2 | 3 | For use-cases that depend on a specific condition to be met, these operators do the trick. 4 | 5 | ## Contents 6 | * [defaultIfEmpty](defaultifempty.md) 7 | * [every](every.md) -------------------------------------------------------------------------------- /operators/conditional/defaultifempty.md: -------------------------------------------------------------------------------- 1 | # defaultIfEmpty 2 | #### 연산자(operator) 정의: `defaultIfEmpty(defaultValue: any): Observable` 3 | 4 | ## Emit given value if nothing is emitted before completion. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Default for empty value 9 | 10 | ( [jsBin](http://jsbin.com/yawumoqatu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8ex96cov/) ) 11 | 12 | ```js 13 | const empty = Rx.Observable.of(); 14 | //emit 'Observable.of() Empty!' when empty, else any values from source 15 | const exampleOne = empty.defaultIfEmpty('Observable.of() Empty!'); 16 | //output: 'Observable.of() Empty!' 17 | const subscribe = exampleOne.subscribe(val => console.log(val)); 18 | ``` 19 | 20 | ##### Example 2: Default for Observable.empty 21 | 22 | ( [jsBin](http://jsbin.com/kojafuvesu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3edw828p/) ) 23 | 24 | ```js 25 | //empty observable 26 | const empty = Rx.Observable.empty(); 27 | //emit 'Observable.empty()!' when empty, else any values from source 28 | const example = empty.defaultIfEmpty('Observable.empty()!'); 29 | //output: 'Observable.empty()!' 30 | const subscribe = example.subscribe(val => console.log(val)); 31 | ``` 32 | 33 | 34 | ### Additional Resources 35 | * [defaultIfEmpty](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-defaultIfEmpty) :newspaper: - Official docs 36 | 37 | --- 38 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/defaultIfEmpty.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/defaultIfEmpty.ts) 39 | -------------------------------------------------------------------------------- /operators/conditional/every.md: -------------------------------------------------------------------------------- 1 | # every 2 | #### 연산자(operator) 정의: `every(predicate: function, thisArg: any): Observable` 3 | 4 | ## If all values pass predicate before completion emit true, else false. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Some values false 9 | 10 | ( [jsBin](http://jsbin.com/cibijotase/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/1b46tsm7/) ) 11 | 12 | ```js 13 | //emit 5 values 14 | const source = Rx.Observable.of(1,2,3,4,5); 15 | const example = source 16 | //is every value even? 17 | .every(val => val % 2 === 0) 18 | //output: false 19 | const subscribe = example.subscribe(val => console.log(val)); 20 | ``` 21 | 22 | ##### Example 2: All values true 23 | 24 | ( [jsBin](http://jsbin.com/yuxefiviko/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x34nLmcj/) ) 25 | 26 | ```js 27 | //emit 5 values 28 | const allEvens = Rx.Observable.of(2,4,6,8,10); 29 | const example = allEvens 30 | //is every value even? 31 | .every(val => val % 2 === 0); 32 | //output: true 33 | const subscribe = example.subscribe(val => console.log(val)); 34 | ``` 35 | 36 | 37 | ### Additional Resources 38 | * [every](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-every) :newspaper: - Official docs 39 | 40 | --- 41 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/every.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/every.ts) 42 | -------------------------------------------------------------------------------- /operators/creation/README.md: -------------------------------------------------------------------------------- 1 | # Creation Operators 2 | 3 | These operators allow the creation of an observable from nearly anything. From generic 4 | to specific use-cases you are free, and encouraged, to turn [everything into a stream](http://slides.com/robwormald/everything-is-a-stream#/). 5 | 6 | ## Contents 7 | * [create](create.md) 8 | * [empty](empty.md) 9 | * [from](from.md) :star: 10 | * [fromEvent](fromevent.md) 11 | * [fromPromise](frompromise.md) :star: 12 | * [interval](interval.md) 13 | * [of](of.md) :star: 14 | * [range](range.md) 15 | * [throw](throw.md) 16 | * [timer](timer.md) 17 | 18 | :star: - *commonly used* 19 | 20 | ### Additional Resources 21 | * [Creating Observables From Scratch](https://egghead.io/courses/rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz -------------------------------------------------------------------------------- /operators/creation/create.md: -------------------------------------------------------------------------------- 1 | # create 2 | #### 연산자(operator) 정의: `create(subscribe: function)` 3 | 4 | ## Create an observable with given subscription function. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Observable that emits multiple values 9 | 10 | ( [jsBin](http://jsbin.com/qorugiwaba/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/td5107he/) ) 11 | 12 | ```js 13 | /* 14 | Create an observable that emits 'Hello' and 'World' on 15 | subscription. 16 | */ 17 | const hello = Rx.Observable.create(function(observer) { 18 | observer.next('Hello'); 19 | observer.next('World'); 20 | }); 21 | 22 | //output: 'Hello'...'World' 23 | const subscribe = hello.subscribe(val => console.log(val)); 24 | ``` 25 | 26 | ##### Example 2: Observable that emits even numbers on timer 27 | 28 | ( [jsBin](http://jsbin.com/lodilohate/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/vtozg6uf/) ) 29 | 30 | ```js 31 | /* 32 | Increment value every 1s, emit even numbers. 33 | */ 34 | const evenNumbers = Rx.Observable.create(function(observer) { 35 | let value = 0; 36 | const interval = setInterval(() => { 37 | if(value % 2 === 0){ 38 | observer.next(value); 39 | } 40 | value++; 41 | }, 1000); 42 | 43 | return () => clearInterval(interval); 44 | }); 45 | //output: 0...2...4...6...8 46 | const subscribe = evenNumbers.subscribe(val => console.log(val)); 47 | //unsubscribe after 10 seconds 48 | setTimeout(() => { 49 | subscribe.unsubscribe(); 50 | }, 10000); 51 | ``` 52 | 53 | 54 | ### Additional Resources 55 | * [create](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-create) :newspaper: - Official docs 56 | * [Creation operators: Create()](https://egghead.io/lessons/rxjs-creation-operator-create?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 57 | * [Using Observable.create for fine-grained control](https://egghead.io/lessons/rxjs-using-observable-create-for-fine-grained-control) :video_camera: :dollar: - Shane Osbourne 58 | 59 | --- 60 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/GenerateObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/GenerateObservable.ts) 61 | -------------------------------------------------------------------------------- /operators/creation/empty.md: -------------------------------------------------------------------------------- 1 | # empty 2 | #### 연산자(operator) 정의: `empty(scheduler: Scheduler): Observable` 3 | 4 | ## Observable that immediately completes. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: empty immediately completes 9 | 10 | ( [jsBin](http://jsbin.com/rodubucaqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/bz71mzuy/) ) 11 | 12 | ```js 13 | //Create observable that immediately completes 14 | const example = Rx.Observable.empty(); 15 | //output: 'Complete!' 16 | const subscribe = example.subscribe({ 17 | next: () => console.log('Next'), 18 | complete: () => console.log('Complete!') 19 | }); 20 | ``` 21 | 22 | ### Follow the Source Code 23 | *Coming soon...* 24 | 25 | 26 | ### Additional Resources 27 | * [empty](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-empty) :newspaper: - Official docs 28 | * [Creation operators: empty, never, and throw](https://egghead.io/lessons/rxjs-creation-operators-empty-never-throw?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 29 | 30 | --- 31 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/EmptyObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/EmptyObservable.ts) 32 | -------------------------------------------------------------------------------- /operators/creation/from.md: -------------------------------------------------------------------------------- 1 | # from 2 | #### 연산자(operator) 정의: `from(ish: ObservableInput, mapFn: function, thisArg: any, scheduler: Scheduler): Observable` 3 | 4 | ## Turn an array, promise, or iterable into an observable. 5 | 6 | --- 7 | :bulb: For arrays and iterables, all contained values will be emitted as a sequence! 8 | 9 | :bulb: This operator can also be used to emit a string as a sequence of characters! 10 | 11 | --- 12 | 13 | ### Examples 14 | 15 | ##### Example 1: Observable from array 16 | 17 | ( [jsBin](http://jsbin.com/foceyuketi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/o7kb5e6j/) ) 18 | 19 | ```js 20 | //emit array as a sequence of values 21 | const arraySource = Rx.Observable.from([1,2,3,4,5]); 22 | //output: 1,2,3,4,5 23 | const subscribe = arraySource.subscribe(val => console.log(val)); 24 | ``` 25 | 26 | ##### Example 2: Observable from promise 27 | 28 | ( [jsBin](http://jsbin.com/tamofinujo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/2czc5sae/) ) 29 | 30 | ```js 31 | //emit result of promise 32 | const promiseSource = Rx.Observable.from(new Promise(resolve => resolve('Hello World!'))); 33 | //output: 'Hello World' 34 | const subscribe = promiseSource.subscribe(val => console.log(val)); 35 | ``` 36 | 37 | ##### Example 3: Observable from collection 38 | 39 | ( [jsBin](http://jsbin.com/tezohobudu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ae6hu9a8/) ) 40 | 41 | ```js 42 | //works on js collections 43 | const map = new Map(); 44 | map.set(1, 'Hi'); 45 | map.set(2, 'Bye'); 46 | 47 | const mapSource = Rx.Observable.from(map); 48 | //output: [1, 'Hi'], [2, 'Bye'] 49 | const subscribe = mapSource.subscribe(val => console.log(val)); 50 | ``` 51 | 52 | ##### Example 4: Observable from string 53 | 54 | ( [jsBin](http://jsbin.com/wenozubana/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/hfvzjcvL/) ) 55 | 56 | ```js 57 | //emit string as a sequence 58 | const source = Rx.Observable.from('Hello World'); 59 | //output: 'H','e','l','l','o',' ','W','o','r','l','d' 60 | const subscribe = source.subscribe(val => console.log(val)); 61 | ``` 62 | 63 | ### Additional Resources 64 | * [from](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-from) :newspaper: - Official docs 65 | * [Creation operators: from, fromArray, fromPromise](https://egghead.io/lessons/rxjs-creation-operators-from-fromarray-frompromise?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 66 | 67 | --- 68 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/FromObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/FromObservable.ts) 69 | -------------------------------------------------------------------------------- /operators/creation/fromevent.md: -------------------------------------------------------------------------------- 1 | # fromEvent 2 | #### 연산자(operator) 정의: `fromEvent(target: EventTargetLike, eventName: string, selector: function): Observable` 3 | 4 | ## Turn event into observable sequence. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Observable from mouse clicks 9 | 10 | ( [jsBin](http://jsbin.com/xikapewoqa/1/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/vbLz1pdx/) ) 11 | 12 | ```js 13 | //create observable that emits click events 14 | const source = Rx.Observable.fromEvent(document, 'click'); 15 | //map to string with given event timestamp 16 | const example = source.map(event => `Event time: ${event.timeStamp}`) 17 | //output (example): 'Event time: 7276.390000000001' 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ### Related Recipes 22 | * [Smart Counter](../../recipes/smartcounter.md) 23 | 24 | ### Additional Resources 25 | * [fromEvent](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-fromEvent) :newspaper: - Official docs 26 | 27 | --- 28 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/FromEventObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/FromEventObservable.ts) 29 | -------------------------------------------------------------------------------- /operators/creation/frompromise.md: -------------------------------------------------------------------------------- 1 | # fromPromise 2 | #### 연산자(operator) 정의: `fromPromise(promise: Promise, scheduler: Scheduler): Observable` 3 | 4 | ## Create observable from promise, emitting result. 5 | 6 | --- 7 | :bulb: Flattening operators can generally accept promises without wrapping! 8 | 9 | :bulb: You could also use [Observable.from](from.md) for the same result! 10 | 11 | --- 12 | 13 | ### Examples 14 | 15 | ##### Example 1: Converting promise to observable and catching errors 16 | 17 | ( [jsBin](http://jsbin.com/cokivecima/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/upy6nr6n/) ) 18 | 19 | ```js 20 | //example promise that will resolve or reject based on input 21 | const myPromise = (willReject) => { 22 | return new Promise((resolve, reject) => { 23 | if(willReject){ 24 | reject('Rejected!'); 25 | } 26 | resolve('Resolved!'); 27 | }) 28 | } 29 | //emit true, then false 30 | const source = Rx.Observable.of(true, false); 31 | const example = source 32 | .mergeMap(val => Rx.Observable 33 | //turn promise into observable 34 | .fromPromise(myPromise(val)) 35 | //catch and gracefully handle rejections 36 | .catch(error => Rx.Observable.of(`Error: ${error}`)) 37 | ) 38 | //output: 'Error: Rejected!', 'Resolved!' 39 | const subscribe = example.subscribe(val => console.log(val)); 40 | ``` 41 | 42 | 43 | ### Additional Resources 44 | * [fromPromise](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-fromPromise) :newspaper: - Official docs 45 | * [Creation operators: from, fromArray, fromPromise](https://egghead.io/lessons/rxjs-creation-operators-from-fromarray-frompromise?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 46 | * [fromPromise - Guide](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/promises.md) 47 | 48 | --- 49 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/PromiseObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/PromiseObservable.ts) 50 | -------------------------------------------------------------------------------- /operators/creation/interval.md: -------------------------------------------------------------------------------- 1 | # interval 2 | #### 연산자(operator) 정의: `interval(period: number, scheduler: Scheduler): Observable` 3 | 4 | ## Emit numbers in sequence based on provided timeframe. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Emit sequence of values at 1 second interval 9 | 10 | ( [jsBin](http://jsbin.com/vigohomabo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x3mrwzr0/) ) 11 | 12 | ```js 13 | //emit value in sequence every 1 second 14 | const source = Rx.Observable.interval(1000); 15 | //output: 0,1,2,3,4,5.... 16 | const subscribe = source.subscribe(val => console.log(val)); 17 | ``` 18 | 19 | ### Additional Resources 20 | * [interval](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-interval) :newspaper: - Official docs 21 | * [Creation operators: interval and timer](https://egghead.io/lessons/rxjs-creation-operators-interval-and-timer?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 22 | 23 | --- 24 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/IntervalObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/IntervalObservable.ts) 25 | -------------------------------------------------------------------------------- /operators/creation/of.md: -------------------------------------------------------------------------------- 1 | # of 2 | #### 연산자(operator) 정의: ` of(...values, scheduler: Scheduler): Observable` 3 | 4 | ## Emit variable amount of values in a sequence. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Emitting a sequence of numbers 9 | 10 | ( [jsBin](http://jsbin.com/kodixitoji/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/f7b35ayz/) ) 11 | 12 | ```js 13 | //emits any number of provided values in sequence 14 | const source = Rx.Observable.of(1,2,3,4,5); 15 | //output: 1,2,3,4,5 16 | const subscribe = source.subscribe(val => console.log(val)); 17 | ``` 18 | 19 | ##### Example 2: Emitting an object, array, and function 20 | 21 | ( [jsBin](http://jsbin.com/xevobujama/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/d9rng4dj/) ) 22 | 23 | ```js 24 | //emits values of any type 25 | const source = Rx.Observable.of({name: 'Brian'}, [1,2,3], function hello(){ return 'Hello'}); 26 | //output: {name: 'Brian}, [1,2,3], function hello() { return 'Hello' } 27 | const subscribe = source.subscribe(val => console.log(val)); 28 | ``` 29 | 30 | 31 | ### Additional Resources 32 | * [of](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-of) :newspaper: - Official docs 33 | * [Creation operators: of](https://egghead.io/lessons/rxjs-creation-operator-of?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 34 | 35 | --- 36 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/ArrayObservable.ts) 37 | -------------------------------------------------------------------------------- /operators/creation/range.md: -------------------------------------------------------------------------------- 1 | # range 2 | #### 연산자(operator) 정의: `range(start: number, count: number, scheduler: Scheduler): Observable` 3 | 4 | ## Emit numbers in provided range in sequence. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Emit range 1-10 9 | 10 | ( [jsBin](http://jsbin.com/yalefomage/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/cfvfgwn9/) ) 11 | 12 | ```js 13 | //emit 1-10 in sequence 14 | const source = Rx.Observable.range(1,10); 15 | //output: 1,2,3,4,5,6,7,8,9,10 16 | const example = source.subscribe(val => console.log(val)); 17 | ``` 18 | 19 | 20 | ### Additional Resources 21 | * [range](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-range) :newspaper: - Official docs 22 | 23 | --- 24 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/RangeObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/RangeObservable.ts) 25 | -------------------------------------------------------------------------------- /operators/creation/throw.md: -------------------------------------------------------------------------------- 1 | # throw 2 | #### 연산자(operator) 정의: `throw(error: any, scheduler: Scheduler): Observable` 3 | 4 | ## Emit error on subscription. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Throw error on subscription 9 | 10 | ( [jsBin](http://jsbin.com/punubequju/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/mks82xqz/) ) 11 | 12 | ```js 13 | //emits an error with specified value on subscription 14 | const source = Rx.Observable.throw('This is an error!'); 15 | //output: 'Error: This is an error!' 16 | const subscribe = source.subscribe({ 17 | next: val => console.log(val), 18 | complete: () => console.log('Complete!'), 19 | error: val => console.log(`Error: ${val}`) 20 | }); 21 | ``` 22 | 23 | 24 | ### Additional Resources 25 | * [throw](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-throw) :newspaper: - Official docs 26 | * [Creation operators: empty, never, and throw](https://egghead.io/lessons/rxjs-creation-operators-empty-never-throw?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 27 | 28 | --- 29 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/ErrorObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/ErrorObservable.ts) 30 | -------------------------------------------------------------------------------- /operators/creation/timer.md: -------------------------------------------------------------------------------- 1 | # timer 2 | #### 연산자(operator) 정의: `timer(initialDelay: number | Date, period: number, scheduler: Scheduler): Observable` 3 | 4 | ## After given duration, emit numbers in sequence every specified duration. 5 | 6 | 7 | ### Examples 8 | 9 | ##### Example 1: timer emits 1 value then completes 10 | 11 | ( [jsBin](http://jsbin.com/pazajanehu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/vpx0y8fu/) ) 12 | 13 | ```js 14 | //emit 0 after 1 second then complete, since no second argument is supplied 15 | const source = Rx.Observable.timer(1000); 16 | //output: 0 17 | const subscribe = source.subscribe(val => console.log(val)); 18 | ``` 19 | 20 | ##### Example 2: timer emits after 1 second, then every 2 seconds 21 | 22 | ( [jsBin](http://jsbin.com/kejidofuje/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/30ddov8j/) ) 23 | 24 | ```js 25 | /* 26 | timer takes a second argument, how often to emit subsequent values 27 | in this case we will emit first value after 1 second and subsequent 28 | values every 2 seconds after 29 | */ 30 | const source = Rx.Observable.timer(1000, 2000); 31 | //output: 0,1,2,3,4,5...... 32 | const subscribe = source.subscribe(val => console.log(val)); 33 | ``` 34 | 35 | 36 | ### Additional Resources 37 | * [timer](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#static-method-timer) :newspaper: - Official docs 38 | * [Creation operators: interval and timer](https://egghead.io/lessons/rxjs-creation-operators-interval-and-timer?course=rxjs-beyond-the-basics-creating-observables-from-scratch) :video_camera: :dollar: - André Staltz 39 | 40 | --- 41 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/observable/TimerObservable.ts](https://github.com/ReactiveX/rxjs/blob/master/src/observable/TimerObservable.ts) 42 | -------------------------------------------------------------------------------- /operators/error_handling/README.md: -------------------------------------------------------------------------------- 1 | # Error Handling Operators 2 | 3 | Errors are an unfortunate side-effect of development. These operators provide effective ways 4 | to gracefully handle errors and retry logic, should they occur. 5 | 6 | ## Contents 7 | * [catch](catch.md) :star: 8 | * [retry](retry.md) 9 | * [retryWhen](retrywhen.md) 10 | 11 | :star: - *commonly used* -------------------------------------------------------------------------------- /operators/error_handling/catch.md: -------------------------------------------------------------------------------- 1 | # catch 2 | #### 연산자(operator) 정의: `catch(project : function): Observable` 3 | 4 | ## Gracefully handle errors in an observable sequence. 5 | 6 | --- 7 | :warning: Remember to return an observable from the catch function! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/error_handling/catch-spec.ts) ) 14 | 15 | ##### Example 1: Catching error from observable 16 | 17 | ( [jsBin](http://jsbin.com/porevoxelu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/wk4oLLqc/) ) 18 | 19 | ```js 20 | //emit error 21 | const source = Rx.Observable.throw('This is an error!'); 22 | //gracefully handle error, returning observable with error message 23 | const example = source.catch(val => Rx.Observable.of(`I caught: ${val}`)); 24 | //output: 'I caught: This is an error' 25 | const subscribe = example.subscribe(val => console.log(val)); 26 | ``` 27 | 28 | ##### Example 2: Catching rejected promise 29 | 30 | ( [jsBin](http://jsbin.com/rusaxubanu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/sLq92gLv/) ) 31 | 32 | ```js 33 | //create promise that immediately rejects 34 | const myBadPromise = () => new Promise((resolve, reject) => reject('Rejected!')); 35 | //emit single value after 1 second 36 | const source = Rx.Observable.timer(1000); 37 | //catch rejected promise, returning observable containing error message 38 | const example = source.flatMap(() => Rx.Observable 39 | .fromPromise(myBadPromise()) 40 | .catch(error => Rx.Observable.of(`Bad Promise: ${error}`)) 41 | ); 42 | //output: 'Bad Promise: Rejected' 43 | const subscribe = example.subscribe(val => console.log(val)); 44 | ``` 45 | 46 | 47 | ### Additional Resources 48 | * [Error handling operator: catch](https://egghead.io/lessons/rxjs-error-handling-operator-catch?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 49 | 50 | --- 51 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/catch.ts) 52 | -------------------------------------------------------------------------------- /operators/error_handling/retry.md: -------------------------------------------------------------------------------- 1 | # retry 2 | #### 연산자(operator) 정의: `retry(number: number): Observable` 3 | 4 | ## Retry an observable sequence a specific number of times should an error occur. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Retry 2 times on error 9 | 10 | ( [jsBin](http://jsbin.com/yovacuxuqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/hg7z16bo/) ) 11 | 12 | ```js 13 | //emit value every 1s 14 | const source = Rx.Observable.interval(1000); 15 | const example = source 16 | .flatMap(val => { 17 | //throw error for demonstration 18 | if(val > 5){ 19 | return Rx.Observable.throw('Error!'); 20 | } 21 | return Rx.Observable.of(val); 22 | }) 23 | //retry 2 times on error 24 | .retry(2); 25 | /* 26 | output: 27 | 0..1..2..3..4..5.. 28 | 0..1..2..3..4..5.. 29 | 0..1..2..3..4..5.. 30 | "Error!: Retried 2 times then quit!" 31 | */ 32 | const subscribe = example 33 | .subscribe({ 34 | next: val => console.log(val), 35 | error: val => console.log(`${val}: Retried 2 times then quit!`) 36 | }); 37 | ``` 38 | 39 | 40 | ### Additional Resources 41 | * [retry](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-retry) :newspaper: - Official docs 42 | * [Error handling operator: retry and retryWhen](https://egghead.io/lessons/rxjs-error-handling-operator-retry-and-retrywhen?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 43 | 44 | --- 45 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/retry.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/retry.ts) 46 | -------------------------------------------------------------------------------- /operators/error_handling/retrywhen.md: -------------------------------------------------------------------------------- 1 | # retryWhen 2 | #### 연산자(operator) 정의: `retryWhen(receives: (errors: Observable) => Observable, the: scheduler): Observable` 3 | 4 | ## Retry an observable sequence on error based on custom criteria. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Trigger retry after specified duration 9 | 10 | ( [jsBin](http://jsbin.com/miduqexalo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/49mkhsyr/) ) 11 | 12 | ```js 13 | //emit value every 1s 14 | const source = Rx.Observable.interval(1000); 15 | const example = source 16 | .map(val => { 17 | if(val > 5){ 18 | //error will be picked up by retryWhen 19 | throw val; 20 | } 21 | return val; 22 | }) 23 | .retryWhen(errors => errors 24 | //log error message 25 | .do(val => console.log(`Value ${val} was too high!`)) 26 | //restart in 5 seconds 27 | .delayWhen(val => Rx.Observable.timer(val * 1000)) 28 | ); 29 | /* 30 | output: 31 | 0 32 | 1 33 | 2 34 | 3 35 | 4 36 | 5 37 | "Value 6 was too high!" 38 | --Wait 5 seconds then repeat 39 | */ 40 | const subscribe = example.subscribe(val => console.log(val)); 41 | ``` 42 | 43 | 44 | ### Additional Resources 45 | * [retryWhen](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-retryWhen) :newspaper: - Official docs 46 | * [Error handling operator: retry and retryWhen](https://egghead.io/lessons/rxjs-error-handling-operator-retry-and-retrywhen?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 47 | 48 | 49 | --- 50 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/retryWhen.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/retryWhen.ts) 51 | -------------------------------------------------------------------------------- /operators/filtering/README.md: -------------------------------------------------------------------------------- 1 | # Filtering Operators 2 | 3 | In a [push based approach](http://reactivex.io/rxjs/manual/overview.html#pull-versus-push), picking and choosing how and when to accept items is important. 4 | These operators provide techniques for accepting values from an observable source and dealing with [backpressure](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/gettingstarted/backpressure.md). 5 | 6 | ## Contents 7 | * [debounce](debounce.md) 8 | * [debounceTime](debouncetime.md) :star: 9 | * [distinctUntilChanged](distinctuntilchanged.md) :star: 10 | * [filter](filter.md) :star: 11 | * [first](first.md) 12 | * [ignoreElements](ignoreelements.md) 13 | * [last](last.md) 14 | * [sample](sample.md) 15 | * [single](single.md) 16 | * [skip](skip.md) 17 | * [skipUntil](skipuntil.md) 18 | * [skipWhile](skipwhile.md) 19 | * [take](take.md) :star: 20 | * [takeUntil](takeuntil.md) :star: 21 | * [takeWhile](takewhile.md) 22 | * [throttle](throttle.md) 23 | * [throttleTime](throttletime.md) 24 | 25 | :star: - *commonly used* 26 | 27 | -------------------------------------------------------------------------------- /operators/filtering/debounce.md: -------------------------------------------------------------------------------- 1 | # debounce 2 | #### 연산자(operator) 정의: `debounce(durationSelector: function): Observable` 3 | 4 | ## Discard emitted values that take less than the specified time, based on selector function, between output. 5 | 6 | --- 7 | :bulb: Though not as widely used as [debounceTime](debouncetime.md), **debounce** is important when the debounce rate is variable! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Debounce on timer 14 | 15 | ( [jsBin](http://jsbin.com/sorimeyoro/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/e5698yow/) ) 16 | 17 | ```js 18 | //emit four strings 19 | const example = Rx.Observable.of('WAIT','ONE','SECOND','Last will display'); 20 | /* 21 | Only emit values after a second has passed between the last emission, 22 | throw away all other values 23 | */ 24 | const debouncedExample = example.debounce(() => Rx.Observable.timer(1000)); 25 | /* 26 | In this example, all values but the last will be omitted 27 | output: 'Last will display' 28 | */ 29 | const subscribe = debouncedExample.subscribe(val => console.log(val)); 30 | ``` 31 | 32 | ##### Example 2: Debounce at increasing interval 33 | 34 | ( [jsBin](http://jsbin.com/sotaretese/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6ab34nq6/) ) 35 | 36 | ```js 37 | //emit value every 1 second, ex. 0...1...2 38 | const interval = Rx.Observable.interval(1000); 39 | //raise the debounce time by 200ms each second 40 | const debouncedInterval = interval.debounce(val => Rx.Observable.timer(val * 200)) 41 | /* 42 | After 5 seconds, debounce time will be greater than interval time, 43 | all future values will be thrown away 44 | output: 0...1...2...3...4......(debounce time over 1s, no values emitted) 45 | */ 46 | const subscribe = debouncedInterval.subscribe(val => console.log(`Example Two: ${val}`)); 47 | ``` 48 | 49 | 50 | ### Additional Resources 51 | * [debounce](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-debounce) :newspaper: - Official docs 52 | * [Transformation operator: debounce and debounceTime](https://egghead.io/lessons/rxjs-transformation-operators-debounce-and-debouncetime?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 53 | 54 | --- 55 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/debounce.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/debounce.ts) 56 | -------------------------------------------------------------------------------- /operators/filtering/debouncetime.md: -------------------------------------------------------------------------------- 1 | # debounceTime 2 | #### 연산자(operator) 정의: `debounceTime(dueTime: number, scheduler: Scheduler): Observable` 3 | 4 | ## Discard emitted values that take less than the specified time between output 5 | 6 | 7 | --- 8 | :bulb: This operator is popular in scenarios such as type-ahead where the rate of user input must be controlled! 9 | 10 | --- 11 | 12 | ### Examples 13 | 14 | ##### Example 1: Debouncing based on time between input 15 | 16 | ( [jsBin](http://jsbin.com/kacijarogi/1/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/7kbg4q2e/) ) 17 | 18 | ```js 19 | const input = document.getElementById('example'); 20 | 21 | //for every keyup, map to current input value 22 | const example = Rx.Observable 23 | .fromEvent(input, 'keyup') 24 | .map(i => i.currentTarget.value); 25 | 26 | //wait .5s between keyups to emit current value 27 | //throw away all other values 28 | const debouncedInput = example.debounceTime(500); 29 | 30 | //log values 31 | const subscribe = debouncedInput.subscribe(val => { 32 | console.log(`Debounced Input: ${val}`); 33 | }); 34 | ``` 35 | 36 | 37 | ### Additional Resources 38 | * [debounceTime](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-debounceTime) :newspaper: - Official docs 39 | * [Transformation operator: debounce and debounceTime](https://egghead.io/lessons/rxjs-transformation-operators-debounce-and-debouncetime?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 40 | 41 | --- 42 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/debounceTime.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/debounceTime.ts) 43 | -------------------------------------------------------------------------------- /operators/filtering/distinctuntilchanged.md: -------------------------------------------------------------------------------- 1 | # distinctUntilChanged 2 | #### 연산자(operator) 정의: ` distinctUntilChanged(compare: function): Observable` 3 | 4 | ## Only emit when the current value is different than the last. 5 | 6 | --- 7 | :bulb: distinctUntilChanged uses `===` comparison by default, object references must match! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: distinctUntilChanged with basic values 14 | 15 | ( [jsBin](http://jsbin.com/qoyoxeheva/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xc2vzct7/) ) 16 | 17 | ```js 18 | //only output distinct values, based on the last emitted value 19 | const myArrayWithDuplicatesInARow = Rx.Observable 20 | .from([1,1,2,2,3,1,2,3]); 21 | 22 | const distinctSub = myArrayWithDuplicatesInARow 23 | .distinctUntilChanged() 24 | //output: 1,2,3,1,2,3 25 | .subscribe(val => console.log('DISTINCT SUB:', val)); 26 | 27 | const nonDistinctSub = myArrayWithDuplicatesInARow 28 | //output: 1,1,2,2,3,1,2,3 29 | .subscribe(val => console.log('NON DISTINCT SUB:', val)); 30 | ``` 31 | 32 | ##### Example 2: distinctUntilChanged with objects 33 | 34 | ( [jsBin](http://jsbin.com/mexocipave/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/t4ava5b4/) ) 35 | 36 | ```js 37 | const sampleObject = {name: 'Test'}; 38 | //Objects must be same reference 39 | const myArrayWithDuplicateObjects = Rx.Observable.from([sampleObject, sampleObject, sampleObject]); 40 | //only out distinct objects, based on last emitted value 41 | const nonDistinctObjects = myArrayWithDuplicateObjects 42 | .distinctUntilChanged() 43 | //output: 'DISTINCT OBJECTS: {name: 'Test'} 44 | .subscribe(val => console.log('DISTINCT OBJECTS:', val)); 45 | ``` 46 | 47 | 48 | ### Additional Resources 49 | * [distinctUntilChanged](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-distinctUntilChanged) :newspaper: - Official docs 50 | * [Filtering operator: distinct and distinctUntilChanged](https://egghead.io/lessons/rxjs-filtering-operators-distinct-and-distinctuntilchanged?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 51 | 52 | --- 53 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/distinctUntilChanged.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/distinctUntilChanged.ts) 54 | -------------------------------------------------------------------------------- /operators/filtering/filter.md: -------------------------------------------------------------------------------- 1 | # filter 2 | #### 연산자(operator) 정의: `filter(select: Function, thisArg: any): Observable` 3 | 4 | ## Emit values that pass the provided condition. 5 | 6 | --- 7 | :bulb: If you would like to complete an observable when a condition fails, check out [takeWhile](takewhile.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: filter for even numbers 14 | 15 | ( [jsBin](http://jsbin.com/vafogoluye/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/tkz0fuy2/) ) 16 | 17 | ```js 18 | //emit (1,2,3,4,5) 19 | const source = Rx.Observable.from([1,2,3,4,5]); 20 | //filter out non-even numbers 21 | const example = source.filter(num => num % 2 === 0); 22 | //output: "Even number: 2", "Even number: 4" 23 | const subscribe = example.subscribe(val => console.log(`Even number: ${val}`)); 24 | ``` 25 | 26 | ##### Example 2: filter objects based on property 27 | 28 | ( [jsBin](http://jsbin.com/qihagaxuso/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/yjdsoug1/) ) 29 | 30 | ```js 31 | //emit ({name: 'Joe', age: 31}, {name: 'Bob', age:25}) 32 | const source = Rx.Observable.from([{name: 'Joe', age: 31}, {name: 'Bob', age:25}]); 33 | //filter out people with age under 30 34 | const example = source.filter(person => person.age >= 30); 35 | //output: "Over 30: Joe" 36 | const subscribe = example.subscribe(val => console.log(`Over 30: ${val.name}`)); 37 | ``` 38 | 39 | ##### Example 3: filter for number greater than specified value 40 | 41 | ( [jsBin](http://jsbin.com/rakabaheyu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g1tgreha/) ) 42 | 43 | ```js 44 | //emit every second 45 | const source = Rx.Observable.interval(1000); 46 | //filter out all values until interval is greater than 5 47 | const example = source.filter(num => num > 5); 48 | /* 49 | "Number greater than 5: 6" 50 | "Number greater than 5: 7" 51 | "Number greater than 5: 8" 52 | "Number greater than 5: 9" 53 | */ 54 | const subscribe = example.subscribe(val => console.log(`Number greater than 5: ${val}`)); 55 | ``` 56 | 57 | ### Additional Resources 58 | * [filter](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-filter) :newspaper: - Official docs 59 | * [Adding conditional logic with filter](https://egghead.io/lessons/rxjs-adding-conditional-logic-with-filter?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 60 | * [Filtering operator: filter](https://egghead.io/lessons/rxjs-filtering-operator-filter?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 61 | 62 | --- 63 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/filter.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/filter.ts) 64 | -------------------------------------------------------------------------------- /operators/filtering/first.md: -------------------------------------------------------------------------------- 1 | #first 2 | #### 연산자(operator) 정의: `first(predicate: function, select: function)` 3 | 4 | ## Emit the first value or first to pass provided expression. 5 | 6 | --- 7 | :bulb: The counterpart to first is [**last**](last.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ( [example tests](https://github.com/btroncone/learn-rxjs/blob/master/operators/specs/filtering/first-spec.ts) ) 14 | 15 | ##### Example 1: First value from sequence 16 | 17 | ( [jsBin](http://jsbin.com/kayenuxoma/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/uncey4v9/) ) 18 | 19 | ```js 20 | const source = Rx.Observable.from([1,2,3,4,5]); 21 | //no arguments, emit first value 22 | const example = source.first(); 23 | //output: "First value: 1" 24 | const subscribe = example.subscribe(val => console.log(`First value: ${val}`)); 25 | ``` 26 | 27 | ##### Example 2: First value to pass predicate 28 | 29 | ( [jsBin](http://jsbin.com/pujowawovu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/pt36r8cu/) ) 30 | 31 | ```js 32 | const source = Rx.Observable.from([1,2,3,4,5]); 33 | //emit first item to pass test 34 | const example = source.first(num => num === 5); 35 | //output: "First to pass test: 5" 36 | const subscribe = example.subscribe(val => console.log(`First to pass test: ${val}`)); 37 | ``` 38 | 39 | ##### Example 3: Using optional projection function 40 | 41 | ( [jsBin](http://jsbin.com/qijekijaja/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qosu0cx6/) ) 42 | 43 | ```js 44 | const source = Rx.Observable.from([1,2,3,4,5]); 45 | //using optional projection function 46 | const example = source.first(num => num % 2 === 0, 47 | (result, index) => `First even: ${result} is at index: ${index}`); 48 | //output: "First even: 2 at index: 1" 49 | const subscribe = example.subscribe(val => console.log(val)); 50 | ``` 51 | 52 | ##### Example 4: Utilizing default value 53 | 54 | ( [jsBin](http://jsbin.com/qoganeleqa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/owx2jdg1/3/) ) 55 | 56 | ```js 57 | const source = Rx.Observable.from([1,2,3,4,5]); 58 | //no value will pass, emit default 59 | const example = source.first(val => val > 5, val => `Value: ${val}`, 'Nothing'); 60 | //output: 'Nothing' 61 | const subscribe = example.subscribe(val => console.log(val)); 62 | ``` 63 | 64 | 65 | ### Additional Resources 66 | * [first](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-first) :newspaper: - Official docs 67 | * [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 68 | 69 | --- 70 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/first.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/first.ts) 71 | -------------------------------------------------------------------------------- /operators/filtering/ignoreelements.md: -------------------------------------------------------------------------------- 1 | # ignoreElements 2 | #### 연산자(operator) 정의: `ignoreElements(): Observable` 3 | 4 | 5 | ## Ignore everything but complete and error. 6 | 7 | 8 | ### Examples 9 | 10 | ##### Example 1: Ignore all elements from source 11 | 12 | ( [jsBin](http://jsbin.com/yiyefelubi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/59scjqss/) ) 13 | 14 | ```js 15 | //emit value every 100ms 16 | const source = Rx.Observable.interval(100); 17 | //ignore everything but complete 18 | const example = source 19 | .take(5) 20 | .ignoreElements(); 21 | //output: "COMPLETE!" 22 | const subscribe = example.subscribe( 23 | val => console.log(`NEXT: ${val}`), 24 | val => console.log(`ERROR: ${val}`), 25 | () => console.log('COMPLETE!') 26 | ); 27 | ``` 28 | 29 | ##### Example 2: Only displaying error 30 | 31 | ( [jsBin](http://jsbin.com/gogonawuze/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/srcwdgw6/) ) 32 | 33 | ```js 34 | //emit value every 100ms 35 | const source = Rx.Observable.interval(100); 36 | //ignore everything but error 37 | const error = source 38 | .flatMap(val => { 39 | if(val === 4){ 40 | return Rx.Observable.throw(`ERROR AT ${val}`); 41 | } 42 | return Rx.Observable.of(val); 43 | }) 44 | .ignoreElements(); 45 | //output: "ERROR: ERROR AT 4" 46 | const subscribe = error.subscribe( 47 | val => console.log(`NEXT: ${val}`), 48 | val => console.log(`ERROR: ${val}`), 49 | () => console.log('SECOND COMPLETE!') 50 | ); 51 | ``` 52 | 53 | 54 | ### Additional Resources 55 | * [ignoreElements](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-ignoreElements) :newspaper: - Official docs 56 | 57 | --- 58 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/ignoreElements.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/ignoreElements.ts) 59 | -------------------------------------------------------------------------------- /operators/filtering/last.md: -------------------------------------------------------------------------------- 1 | #last 2 | #### 연산자(operator) 정의: `last(predicate: function): Observable` 3 | 4 | ## Emit the last value emitted from source on completion, based on provided expression. 5 | 6 | --- 7 | :bulb: The counterpart to last is [**first**](first.md)! 8 | 9 | --- 10 | 11 | 12 | ### Examples 13 | 14 | ##### Example 1: Last value in sequence 15 | 16 | ( [jsBin](http://jsbin.com/pevaqeloki/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b05r434a/) ) 17 | 18 | ```js 19 | const source = Rx.Observable.from([1,2,3,4,5]); 20 | //no arguments, emit last value 21 | const example = source.last(); 22 | //output: "Last value: 5" 23 | const subscribe = example.subscribe(val => console.log(`Last value: ${val}`)); 24 | ``` 25 | 26 | ##### Example 2: Last value to pass predicate 27 | 28 | ( [jsBin](http://jsbin.com/yagexuwari/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/pkx2btsh/) ) 29 | 30 | ```js 31 | const source = Rx.Observable.from([1,2,3,4,5]); 32 | //emit last even number 33 | const exampleTwo = source.last(num => num % 2 === 0); 34 | //output: "Last to pass test: 4" 35 | const subscribeTwo = exampleTwo.subscribe(val => console.log(`Last to pass test: ${val}`)); 36 | ``` 37 | 38 | ##### Example 3: Last with result selector 39 | 40 | ( [jsBin](http://jsbin.com/hobinukisu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/76247162/) ) 41 | 42 | ```js 43 | const source = Rx.Observable.from([1,2,3,4,5]); 44 | //supply an option projection function for the second parameter 45 | const exampleTwo = source.last(v => v > 4, v => `The highest emitted number was ${v}`); 46 | //output: 'The highest emitted number was 5' 47 | const subscribeTwo = exampleTwo.subscribe(val => console.log(val)); 48 | ``` 49 | 50 | ##### Example 4: Last with default value 51 | 52 | ( [jsBin](http://jsbin.com/fudubebabi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/L7fbx3vp/) ) 53 | 54 | ```js 55 | const source = Rx.Observable.from([1,2,3,4,5]); 56 | //no values will pass given predicate, emit default 57 | const exampleTwo = source.last(v => v > 5, v => v, 'Nothing!'); 58 | //output: 'Nothing!' 59 | const subscribeTwo = exampleTwo.subscribe(val => console.log(val)); 60 | ``` 61 | 62 | 63 | ### Additional Resources 64 | * [last](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-last) :newspaper: - Official docs 65 | * [Filtering operator: takeLast, last](https://egghead.io/lessons/rxjs-filtering-operators-takelast-last?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 66 | 67 | --- 68 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/last.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/last.ts) 69 | -------------------------------------------------------------------------------- /operators/filtering/sample.md: -------------------------------------------------------------------------------- 1 | # sample 2 | #### 연산자(operator) 정의: `sample(sampler: Observable): Observable` 3 | 4 | ## Sample from source when provided observable emits. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Sample source every 2 seconds 9 | 10 | ( [jsBin](http://jsbin.com/gemebopifu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/8wsbuvjb/) ) 11 | 12 | ```js 13 | //emit value every 1s 14 | const source = Rx.Observable.interval(1000); 15 | //sample last emitted value from source every 2s 16 | const example = source.sample(Rx.Observable.interval(2000)); 17 | //output: 2..4..6..8.. 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ##### Example 2: Sample source when interval emits 22 | 23 | ( [jsBin](http://jsbin.com/cunicepube/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b33kg9dn/) ) 24 | 25 | ```js 26 | const source = Rx.Observable.zip( 27 | //emit 'Joe', 'Frank' and 'Bob' in sequence 28 | Rx.Observable.from(['Joe', 'Frank', 'Bob']), 29 | //emit value every 2s 30 | Rx.Observable.interval(2000) 31 | ); 32 | //sample last emitted value from source every 2.5s 33 | const example = source.sample(Rx.Observable.interval(2500)); 34 | //output: ["Joe", 0]...["Frank", 1]........... 35 | const subscribe = example.subscribe(val => console.log(val)); 36 | ``` 37 | 38 | 39 | ### Additional Resources 40 | * [sample](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-sample) :newspaper: - Official docs 41 | 42 | --- 43 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/sample.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/sample.ts) 44 | -------------------------------------------------------------------------------- /operators/filtering/single.md: -------------------------------------------------------------------------------- 1 | # single 2 | #### 연산자(operator) 정의: `single(a: Function): Observable` 3 | 4 | ## Emit single item that passes expression. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Emit first number passing predicate 9 | 10 | ( [jsBin](http://jsbin.com/solecibuza/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/26r5y90s/) ) 11 | 12 | ```js 13 | //emit (1,2,3,4,5) 14 | const source = Rx.Observable.from([1,2,3,4,5]); 15 | //emit one item that matches predicate 16 | const example = source.single(val => val === 4); 17 | //output: 4 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | 22 | ### Additional Resources 23 | * [single](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-single) :newspaper: - Official docs 24 | 25 | --- 26 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/single.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/single.ts) 27 | -------------------------------------------------------------------------------- /operators/filtering/skip.md: -------------------------------------------------------------------------------- 1 | # skip 2 | #### 연산자(operator) 정의: `skip(the: Number): Observable` 3 | 4 | ## Skip the provided number of emitted values. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Skipping values before emission 9 | 10 | ( [jsBin](http://jsbin.com/hacepudabi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ar1eqbya/) ) 11 | 12 | ```js 13 | //emit every 1s 14 | const source = Rx.Observable.interval(1000); 15 | //skip the first 5 emitted values 16 | const example = source.skip(5); 17 | //output: 5...6...7...8........ 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | 22 | ### Additional Resources 23 | * [skip](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-skip) :newspaper: - Official docs 24 | * [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 25 | 26 | --- 27 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/skip.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/skip.ts) 28 | -------------------------------------------------------------------------------- /operators/filtering/skipuntil.md: -------------------------------------------------------------------------------- 1 | # skipUntil 2 | #### 연산자(operator) 정의: `skipUntil(the: Observable): Observable` 3 | 4 | ## Skip emitted values from source until provided observable emits. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Skip until observable emits 9 | 10 | ( [jsBin](http://jsbin.com/tapizososu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xLu8nf77/) ) 11 | 12 | ```js 13 | //emit every 1s 14 | const source = Rx.Observable.interval(1000); 15 | //skip emitted values from source until inner observable emits (6s) 16 | const example = source.skipUntil(Rx.Observable.timer(6000)); 17 | //output: 5...6...7...8........ 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | 22 | ### Additional Resources 23 | * [skipUntil](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-skipUntil) :newspaper: - Official docs 24 | 25 | --- 26 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/skipUntil.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/skipUntil.ts) 27 | -------------------------------------------------------------------------------- /operators/filtering/skipwhile.md: -------------------------------------------------------------------------------- 1 | # skipWhile 2 | #### 연산자(operator) 정의: `skipWhile(predicate: Function): Observable` 3 | 4 | ## Skip emitted values from source until provided expression is false. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Skip while values below threshold 9 | 10 | ( [jsBin](http://jsbin.com/bemikuleya/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3ymfxb09/) ) 11 | 12 | ```js 13 | //emit every 1s 14 | const source = Rx.Observable.interval(1000); 15 | //skip emitted values from source while value is less than 5 16 | const example = source.skipWhile(val => val < 5); 17 | //output: 5...6...7...8........ 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | 22 | ### Additional Resources 23 | * [skipWhile](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-skipWhile) :newspaper: - Official docs 24 | 25 | --- 26 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/skipWhile.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/skipWhile.ts) 27 | -------------------------------------------------------------------------------- /operators/filtering/take.md: -------------------------------------------------------------------------------- 1 | # take 2 | #### 연산자(operator) 정의: ` take(count: number): Observable` 3 | 4 | ## Emit provided number of values before completing. 5 | 6 | --- 7 | :bulb: If you want to take a variable number of values based on some logic, or another observable, you can use [takeUntil](takeuntil.md) or [takeWhile](takewhile.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Take 1 value from source 14 | 15 | ( [jsBin](http://jsbin.com/vaxitupiwi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/f9bz0tr3/) ) 16 | 17 | ```js 18 | //emit 1,2,3,4,5 19 | const source = Rx.Observable.of(1,2,3,4,5); 20 | //take the first emitted value then complete 21 | const example = source.take(1); 22 | //output: 1 23 | const subscribe = example.subscribe(val => console.log(val)); 24 | ``` 25 | 26 | ##### Example 2: Take the first 5 values from source 27 | 28 | ( [jsBin](http://jsbin.com/kexenuzulu/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g1fhxgua/) ) 29 | 30 | ```js 31 | //emit value every 1s 32 | const interval = Rx.Observable.interval(1000); 33 | //take the first 5 emitted values 34 | const example = interval.take(5); 35 | //output: 0,1,2,3,4 36 | const subscribe = example.subscribe(val => console.log(val)); 37 | ``` 38 | 39 | 40 | ### Additional Resources 41 | * [take](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-take) :newspaper: - Official docs 42 | * [Filtering operator: take, first, skip](https://egghead.io/lessons/rxjs-filtering-operators-take-first-skip?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 43 | 44 | --- 45 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/take.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/take.ts) 46 | -------------------------------------------------------------------------------- /operators/filtering/takeuntil.md: -------------------------------------------------------------------------------- 1 | # takeUntil 2 | #### 연산자(operator) 정의: ` takeUntil(notifier: Observable): Observable` 3 | 4 | ## Emit values until provided observable emits. 5 | 6 | --- 7 | :bulb: If you only need a specific number of values, try [take](take.md)! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Take values until timer emits 14 | 15 | ( [jsBin](http://jsbin.com/yevuhukeja/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/zbe9dzb9/) ) 16 | 17 | ```js 18 | //emit value every 1s 19 | const source = Rx.Observable.interval(1000); 20 | //after 5 seconds, emit value 21 | const timer = Rx.Observable.timer(5000); 22 | //when timer emits after 5s, complete source 23 | const example = source.takeUntil(timer); 24 | //output: 0,1,2,3 25 | const subscribe = example.subscribe(val => console.log(val)); 26 | ``` 27 | 28 | ##### Example 2: Take the first 5 even numbers 29 | 30 | ( [jsBin](http://jsbin.com/doquqecara/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/0dLeksLe/) ) 31 | 32 | ```js 33 | //emit value every 1s 34 | const source = Rx.Observable.interval(1000); 35 | //is number even? 36 | const isEven = val => val % 2 === 0; 37 | //only allow values that are even 38 | const evenSource = source.filter(isEven); 39 | //keep a running total of the number of even numbers out 40 | const evenNumberCount = evenSource 41 | .scan((acc, _) => acc + 1, 0); 42 | //do not emit until 5 even numbers have been emitted 43 | const fiveEvenNumbers = evenNumberCount.filter(val => val > 5); 44 | 45 | const example = evenSource 46 | //also give me the current even number count for display 47 | .withLatestFrom(evenNumberCount) 48 | .map(([val, count]) => `Even number (${count}) : ${val}`) 49 | //when five even numbers have been emitted, complete source observable 50 | .takeUntil(fiveEvenNumbers); 51 | /* 52 | Even number (1) : 0, 53 | Even number (2) : 2 54 | Even number (3) : 4 55 | Even number (4) : 6 56 | Even number (5) : 8 57 | */ 58 | const subscribe = example.subscribe(val => console.log(val)); 59 | ``` 60 | 61 | 62 | ### Additional Resources 63 | * [takeUntil](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-takeUntil) :newspaper: - Official docs 64 | * [Stopping a stream with takeUntil](https://egghead.io/lessons/rxjs-stopping-a-stream-with-takeuntil?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 65 | 66 | --- 67 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/takeUntil.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/takeUntil.ts) 68 | -------------------------------------------------------------------------------- /operators/filtering/takewhile.md: -------------------------------------------------------------------------------- 1 | # takeWhile 2 | #### 연산자(operator) 정의: `takeWhile(predicate: function(value, index): boolean): Observable` 3 | 4 | ## Emit values until provided expression is false. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Take values under limit 9 | 10 | ( [jsBin](http://jsbin.com/zanefaqexu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/yakd4jgc/) ) 11 | 12 | ```js 13 | //emit 1,2,3,4,5 14 | const source = Rx.Observable.of(1,2,3,4,5); 15 | //allow values until value from source is greater than 4, then complete 16 | const example = source.takeWhile(val => val <= 4); 17 | //output: 1,2,3,4 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ### Related Recipes 22 | * [Smart Counter](../../recipes/smartcounter.md) 23 | 24 | ### Additional Resources 25 | * [takeWhile](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-takeWhile) :newspaper: - Official docs 26 | * [Completing a stream with takeWhile](https://egghead.io/lessons/rxjs-completing-a-stream-with-takewhile?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 27 | 28 | --- 29 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/takeWhile.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/takeWhile.ts) 30 | -------------------------------------------------------------------------------- /operators/filtering/throttle.md: -------------------------------------------------------------------------------- 1 | # throttle 2 | #### 연산자(operator) 정의: `throttle(durationSelector: function(value): Observable | Promise): Observable` 3 | 4 | ## Emit value only when duration, determined by provided function, has passed. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Throttle for 2 seconds, based on second observable 9 | 10 | ( [jsBin](http://jsbin.com/wohefujipo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/h8na4m0p/) ) 11 | 12 | ```js 13 | //emit value every 1 second 14 | const source = Rx.Observable.interval(1000); 15 | //throttle for 2 seconds, emit latest value 16 | const example = source.throttle(val => Rx.Observable.interval(2000)); 17 | //output: 0...3...6...9 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ##### Example 2: Throttle with promise 22 | 23 | ( [jsBin](http://jsbin.com/seyaguwunu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/w5Lbzz9f/) ) 24 | 25 | ```js 26 | //emit value every 1 second 27 | const source = Rx.Observable.interval(1000); 28 | //incrementally increase the time to resolve based on source 29 | const promise = val => new Promise(resolve => setTimeout(() => resolve(`Resolved: ${val}`), val * 100)); 30 | //when promise resolves emit item from source 31 | const example = source 32 | .throttle(promise) 33 | .map(val => `Throttled off Promise: ${val}`); 34 | 35 | const subscribe = example.subscribe(val => console.log(val)); 36 | ``` 37 | 38 | 39 | ### Additional Resources 40 | * [throttle](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-throttle) :newspaper: - Official docs 41 | * [Filtering operator: throttle and throttleTime](https://egghead.io/lessons/rxjs-filtering-operators-throttle-and-throttletime?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 42 | 43 | --- 44 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/throttle.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/throttle.ts) 45 | -------------------------------------------------------------------------------- /operators/filtering/throttletime.md: -------------------------------------------------------------------------------- 1 | # throttleTime 2 | #### 연산자(operator) 정의: `throttleTime(duration: number, scheduler: Scheduler): Observable` 3 | 4 | ## Emit latest value when specified duration has passed. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Receieve latest value every 5 seconds 9 | 10 | ( [jsBin](http://jsbin.com/koqujayizo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/4zysLc3y/) ) 11 | 12 | ```js 13 | //emit value every 1 second 14 | const source = Rx.Observable.interval(1000); 15 | /* 16 | throttle for five seconds 17 | last value emitted before throttle ends will be emitted from source 18 | */ 19 | const example = source 20 | .throttleTime(5000); 21 | //output: 0...6...12 22 | const subscribe = example.subscribe(val => console.log(val)); 23 | ``` 24 | 25 | ##### Example 2: Throttle merged observable 26 | 27 | ( [jsBin](http://jsbin.com/takipadaza/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xhd1zy3m/) ) 28 | 29 | ```js 30 | const source = Rx.Observable 31 | .merge( 32 | //emit every .75 seconds 33 | Rx.Observable.interval(750), 34 | //emit every 1 second 35 | Rx.Observable.interval(1000) 36 | ); 37 | //throttle in middle of emitted values 38 | const example = source.throttleTime(1200); 39 | //output: 0...1...4...4...8...7 40 | const subscribe = example.subscribe(val => console.log(val)); 41 | ``` 42 | 43 | 44 | ### Additional Resources 45 | * [throttleTime](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-throttleTime) :newspaper: - Official docs 46 | * [Filtering operator: throttle and throttleTime](https://egghead.io/lessons/rxjs-filtering-operators-throttle-and-throttletime?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 47 | 48 | --- 49 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/throttleTime.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/throttleTime.ts) 50 | -------------------------------------------------------------------------------- /operators/multicasting/README.md: -------------------------------------------------------------------------------- 1 | # Multicasting Operators 2 | 3 | In RxJS observables are cold, or unicast by default. These operators can make an observable hot, or multicast, allowing 4 | side-effects to be share among multiple subscribers. 5 | 6 | ## Contents 7 | * [publish](publish.md) 8 | * [multicast](multicast.md) 9 | * [share](share.md) :star: 10 | 11 | :star: - *commonly used* 12 | 13 | ### Additional Resources 14 | * [Hot vs Cold Observables](https://medium.com/@benlesh/hot-vs-cold-observables-f8094ed53339#.8x9uam5rg) :newspaper: - Ben Lesh 15 | * [Unicast v Multicast](https://github.com/zenparsing/es-observable/issues/66) :newspaper: - GitHub Discussion 16 | * [Demystifying Hot and Cold Observables](https://egghead.io/lessons/rxjs-demystifying-cold-and-hot-observables-in-rxjs) :video_camera: - André Staltz 17 | -------------------------------------------------------------------------------- /operators/multicasting/multicast.md: -------------------------------------------------------------------------------- 1 | # multicast 2 | #### 연산자(operator) 정의: `multicast(selector: Function): Observable` 3 | 4 | ## Share source utilizing the provided Subject. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: multicast with standard Subject 9 | 10 | ( [jsBin](http://jsbin.com/zexuyosuvi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/x2z7p1gm/) ) 11 | 12 | ```js 13 | //emit every 2 seconds, take 5 14 | const source = Rx.Observable.interval(2000).take(5); 15 | 16 | const example = source 17 | //since we are multicasting below, side effects will be executed once 18 | .do(() => console.log('Side Effect #1')) 19 | .mapTo('Result!') 20 | 21 | //subscribe subject to source upon connect() 22 | const multi = example.multicast(() => new Rx.Subject()); 23 | /* 24 | subscribers will share source 25 | output: 26 | "Side Effect #1" 27 | "Result!" 28 | "Result!" 29 | ... 30 | */ 31 | const subscriberOne = multi.subscribe(val => console.log(val)); 32 | const subscriberTwo = multi.subscribe(val => console.log(val)); 33 | //subscribe subject to source 34 | multi.connect(); 35 | ``` 36 | 37 | ##### Example 2: multicast with ReplaySubject 38 | 39 | ( [jsBin](http://jsbin.com/ruhexuhike/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/oj68u58j/) ) 40 | 41 | ```js 42 | //emit every 2 seconds, take 5 43 | const source = Rx.Observable.interval(2000).take(5); 44 | 45 | //example with ReplaySubject 46 | const example = source 47 | //since we are multicasting below, side effects will be executed once 48 | .do(() => console.log('Side Effect #2')) 49 | .mapTo('Result Two!') 50 | //can use any type of subject 51 | const multi = example.multicast(() => new Rx.ReplaySubject(5)); 52 | //subscribe subject to source 53 | multi.connect(); 54 | 55 | setTimeout(() => { 56 | /* 57 | subscriber will receieve all previous values on subscription because 58 | of ReplaySubject 59 | */ 60 | const subscriber = multi 61 | .subscribe(val => console.group(val)); 62 | }, 5000); 63 | ``` 64 | 65 | 66 | ### Additional Resources 67 | * [multicast](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-multicast) :newspaper: - Official docs 68 | 69 | --- 70 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/multicast.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/multicast.ts) 71 | -------------------------------------------------------------------------------- /operators/multicasting/publish.md: -------------------------------------------------------------------------------- 1 | # publish 2 | #### 연산자(operator) 정의: `publish() : ConnectableObservable` 3 | 4 | ## Share source and make hot by calling connect. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Connect observable after subscribers 9 | 10 | ( [jsBin](http://jsbin.com/laguvecixi/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/fpe6csaz/) ) 11 | 12 | ```js 13 | //emit value every 1 second 14 | const source = Rx.Observable.interval(1000); 15 | const example = source 16 | //side effects will be executed once 17 | .do(() => console.log('Do Something!')) 18 | //do nothing until connect() is called 19 | .publish(); 20 | 21 | /* 22 | source will not emit values until connect() is called 23 | output: (after 5s) 24 | "Do Something!" 25 | "Subscriber One: 0" 26 | "Subscriber Two: 0" 27 | "Do Something!" 28 | "Subscriber One: 1" 29 | "Subscriber Two: 1" 30 | */ 31 | const subscribe = example.subscribe(val => console.log(`Subscriber One: ${val}`)); 32 | const subscribeTwo = example.subscribe(val => console.log(`Subscriber Two: ${val}`)); 33 | 34 | //call connect after 5 seconds, causing source to begin emitting items 35 | setTimeout(() => { 36 | example.connect(); 37 | },5000) 38 | ``` 39 | 40 | 41 | ### Additional Resources 42 | * [publish](http://reactivex-rxjs5.surge.sh/function/index.html#static-function-publish) :newspaper: - Official docs 43 | 44 | 45 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/publish.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/publish.ts) 46 | -------------------------------------------------------------------------------- /operators/multicasting/share.md: -------------------------------------------------------------------------------- 1 | # share 2 | #### 연산자(operator) 정의: `share(): Observable` 3 | 4 | ## Share source among multiple subscribers. 5 | 6 | --- 7 | :bulb: share is like [multicast](multicast.md) with a Subject and refCount! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Multiple subscribers sharing source 14 | 15 | ( [jsBin](http://jsbin.com/jobiyomari/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/Lmesxxaq/) ) 16 | 17 | ```js 18 | //emit value in 1s 19 | const source = Rx.Observable.timer(1000); 20 | //log side effect, emit result 21 | const example = source 22 | .do(() => console.log('***SIDE EFFECT***')) 23 | .mapTo('***RESULT***'); 24 | /* 25 | ***NOT SHARED, SIDE EFFECT WILL BE EXECUTED TWICE*** 26 | output: 27 | "***SIDE EFFECT***" 28 | "***RESULT***" 29 | "***SIDE EFFECT***" 30 | "***RESULT***" 31 | */ 32 | const subscribe = example.subscribe(val => console.log(val)); 33 | const subscribeTwo = example.subscribe(val => console.log(val)); 34 | 35 | //share observable among subscribers 36 | const sharedExample = example.share(); 37 | /* 38 | ***SHARED, SIDE EFFECT EXECUTED ONCE*** 39 | output: 40 | "***SIDE EFFECT***" 41 | "***RESULT***" 42 | "***RESULT***" 43 | */ 44 | const subscribeThree = sharedExample.subscribe(val => console.log(val)); 45 | const subscribeFour = sharedExample.subscribe(val => console.log(val)); 46 | ``` 47 | 48 | 49 | ### Additional Resources 50 | * [share](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-share) :newspaper: - Official docs 51 | * [Sharing streams with share](https://egghead.io/lessons/rxjs-sharing-streams-with-share?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 52 | 53 | --- 54 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/share.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/share.ts) 55 | -------------------------------------------------------------------------------- /operators/specs/combination/combineall-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/of'; 4 | import 'rxjs/add/observable/interval'; 5 | import 'rxjs/add/operator/map'; 6 | import 'rxjs/add/operator/combineall'; 7 | import 'rxjs/add/operator/take'; 8 | 9 | describe('The combineAll operator examples', () => { 10 | describe('Example 1 - mapping to an inner observable', () => { 11 | it('should emit the result of both observables as an array', (done) => { 12 | let results = []; 13 | const source = Observable.interval(1000).take(2); 14 | const example = source.map(val => Observable.of(val)); 15 | const combined = example.combineAll(); 16 | const expected = [[0,1]]; 17 | combined.subscribe({ 18 | next: val => results.push(val), 19 | complete: () => { 20 | expect(results).toDeepEqual(expected); 21 | done(); 22 | } 23 | }); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /operators/specs/combination/combinelatest-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/combinelatest'; 4 | 5 | describe('The combineLatest operator examples', () => { 6 | describe('Example 1 - Combining observables emitting at 3 intervals', () => { 7 | it('should combine three observables emitting at seperate intervals', () => { 8 | const t1 = hot( 'a----b-----c---|'); 9 | const t2 = hot( '-----e------f--------|'); 10 | const t3 = hot( '-------------h-----i---------|') 11 | const expected = '-------------y-----z---------|'; 12 | var combined = Observable.combineLatest(t1, t2, t3, (a,b,c) => a + b + c); 13 | expectObservable(combined).toBe(expected, { y: 'cfh', z: 'cfi'}); 14 | }); 15 | }); 16 | }); -------------------------------------------------------------------------------- /operators/specs/combination/concat-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/of'; 4 | import 'rxjs/add/observable/concat'; 5 | import 'rxjs/add/operator/concat'; 6 | import 'rxjs/add/operator/delay'; 7 | 8 | describe('The concat operator examples', () => { 9 | describe('Example 1 - concat 2 basic observables', () => { 10 | it('should emit values from sourceTwo after sourceOne', () => { 11 | const sourceOne = Observable.of(1,2,3); 12 | const sourceTwo = Observable.of(4,5,6); 13 | const example = sourceOne.concat(sourceTwo); 14 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}; 15 | const expected = '(abcdef|)'; 16 | 17 | expectObservable(example).toBe(expected, values); 18 | }); 19 | }); 20 | 21 | describe('Example 2 - concat as static method', () => { 22 | it('should emit values from sourceTwo after sourceOne when used as static method', () => { 23 | const sourceOne = Observable.of(1,2,3); 24 | const sourceTwo = Observable.of(4,5,6); 25 | const example = Observable.concat(sourceOne,sourceTwo); 26 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}; 27 | const expected = '(abcdef|)'; 28 | 29 | expectObservable(example).toBe(expected, values); 30 | }); 31 | }); 32 | 33 | describe('Example 3 - concat with a delayed source', () => { 34 | it('should emit values from sourceTwo after delayed sourceThree completes', () => { 35 | const sourceOne = Observable.of(1,2,3); 36 | const sourceTwo = Observable.of(4,5,6); 37 | const sourceThree = sourceOne.delay(20, rxTestScheduler); 38 | const example = sourceThree.concat(sourceTwo); 39 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 6}; 40 | const expected = '--(abcdef|)'; 41 | 42 | expectObservable(example).toBe(expected, values); 43 | }); 44 | }); 45 | }); -------------------------------------------------------------------------------- /operators/specs/combination/concatall-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/of'; 4 | import 'rxjs/add/operator/concatAll'; 5 | import 'rxjs/add/operator/map'; 6 | 7 | describe('The concatAll operator examples', () => { 8 | describe('Example 1 - concatAll with observable', () => { 9 | it('should subscribe to inner observables, emitting the result', () => { 10 | const values = { 11 | a: 1, 12 | b: 2, 13 | c: 3, 14 | d: 1 + 10, 15 | e: 2 + 10, 16 | f: 3 + 10 17 | }; 18 | const source = cold('---a---b---c|', values); 19 | const example = source 20 | .map(val => Observable.of(val + 10)) 21 | .concatAll(); 22 | const expected = '---d---e---f|'; 23 | 24 | expectObservable(example).toBe(expected, values); 25 | }); 26 | }); 27 | 28 | describe('Example 2 - concatAll with promise', () => { 29 | it('should emit the result of promises', (done) => { 30 | let results = []; 31 | const samplePromise = val => new Promise(resolve => resolve(val + 10)); 32 | const values = { 33 | a: 1, 34 | b: 2, 35 | c: 3, 36 | d: 1 + 10, 37 | e: 2 + 10, 38 | f: 3 + 10 39 | }; 40 | const source = Observable.of(1,2,3); 41 | const example = source 42 | .map(val => samplePromise(val)) 43 | .concatAll(); 44 | 45 | example.subscribe({ 46 | next: val => results.push(val), 47 | complete: () => { 48 | expect(results).toDeepEqual([11,12,13]); 49 | done(); 50 | } 51 | }); 52 | }); 53 | }); 54 | }); -------------------------------------------------------------------------------- /operators/specs/combination/mergeall-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/of'; 4 | import 'rxjs/add/operator/map'; 5 | import 'rxjs/add/operator/mergeall'; 6 | 7 | describe('The concat operator examples', () => { 8 | describe('Example 1 - mergeAll with promises', () => { 9 | it('should emit the result of promises', (done) => { 10 | const results = []; 11 | const myPromise = val => new Promise(resolve => resolve(`Result: ${val}`)) 12 | const source = Observable.of(1,2,3); 13 | const example = source 14 | .map(val => myPromise(val)) 15 | .mergeAll(); 16 | const expected = ['Result: 1', 'Result: 2', 'Result: 3']; 17 | example.subscribe({ 18 | next: val => results.push(val), 19 | complete: () => { 20 | expect(results).toDeepEqual(expected); 21 | done(); 22 | } 23 | }); 24 | }); 25 | }); 26 | }); -------------------------------------------------------------------------------- /operators/specs/combination/startwith-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/observable/interval'; 4 | import 'rxjs/add/observable/of'; 5 | import 'rxjs/add/observable/interval'; 6 | import 'rxjs/add/operator/startWith'; 7 | import 'rxjs/add/operator/scan'; 8 | import 'rxjs/add/operator/take'; 9 | 10 | describe('The startWith operator examples', () => { 11 | describe('Example 1 - startWith on number sequence', () => { 12 | it('should start the sequence with 0', () => { 13 | const source = Observable.of(1,2,3); 14 | const example = source.startWith(0); 15 | const values = {a: 0, b: 1, c: 2, d: 3}; 16 | const expected = '(abcd|)'; 17 | 18 | expectObservable(example).toBe(expected, values); 19 | }); 20 | }); 21 | 22 | describe('Example 2: startWith for initial scan value', () => { 23 | it('should start with initial scan value', () => { 24 | const source = Observable.of('World!', 'Goodbye', 'World!'); 25 | const example = source 26 | .startWith('Hello') 27 | .scan((acc, curr) => `${acc} ${curr}`); 28 | const values = {a: 'Hello', b: 'Hello World!', c: 'Hello World! Goodbye', d: 'Hello World! Goodbye World!'}; 29 | const expected = '(abcd|)'; 30 | 31 | expectObservable(example).toBe(expected, values); 32 | }); 33 | }); 34 | 35 | describe('Example 3: startWith multiple values', () => { 36 | it('should start with -3, -2, -1', () => { 37 | //reducing interval for testing purposes 38 | const source = Observable.interval(-1, rxTestScheduler); 39 | const example = source.startWith(-3, -2, -1).take(4); 40 | const values = {a: -3, b: -2, c: -1, d: 0}; 41 | const expected = '(abcd|))'; 42 | 43 | expectObservable(example).toBe(expected, values); 44 | }); 45 | }); 46 | }); -------------------------------------------------------------------------------- /operators/specs/error_handling/catch-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/operator/catch'; 4 | import 'rxjs/add/operator/mergeMap'; 5 | import 'rxjs/add/observable/of'; 6 | 7 | describe('The catch operator examples', () => { 8 | 9 | describe('Example 1 - Catching error from observable', () => { 10 | it('catch an error', () => { 11 | const source = cold('#') 12 | const example = source.catch(_ => Observable.of('Error Caught!')); 13 | const expected = '(a|)'; 14 | 15 | expectObservable(example).toBe(expected, {a: 'Error Caught!'}); 16 | }); 17 | }); 18 | 19 | describe('Example 2 - Catching rejected promise', () => { 20 | it('catch an error from a rejected promise', (done) => { 21 | let result; 22 | const badPromise = val => new Promise((resolve, reject) => reject('Rejected!')) 23 | const source = Observable.of(true); 24 | const example = source 25 | .mergeMap(val => badPromise(val)) 26 | .catch(err => Observable.of(err)); 27 | 28 | const expected = 'Rejected!'; 29 | 30 | example.subscribe({ 31 | next: val => result = val, 32 | complete: () => { 33 | expect(result).toBe('Rejected!'); 34 | done(); 35 | } 36 | }); 37 | }); 38 | }); 39 | }); -------------------------------------------------------------------------------- /operators/specs/filtering/first-spec.ts: -------------------------------------------------------------------------------- 1 | declare var describe, it, expect, hot, cold, expectObservable, expectSubscriptions, rxTestScheduler, beforeEach; 2 | import {Observable} from 'rxjs/Observable'; 3 | import 'rxjs/add/operator/first'; 4 | import 'rxjs/add/operator/mergeMap'; 5 | import 'rxjs/add/observable/of'; 6 | import 'rxjs/add/observable/from'; 7 | 8 | describe('The first operator examples', () => { 9 | 10 | describe('Example 1 - First value from sequence', () => { 11 | it('should emit the first value then complete', () => { 12 | const source = Observable.from([1,2,3,4,5]); 13 | const example = source.first(); 14 | const expected = '(a|)'; 15 | 16 | expectObservable(example).toBe(expected, {a: 1}); 17 | }); 18 | }); 19 | 20 | describe('Example 2 - First value to pass predicate', () => { 21 | it('should emit the first value to pass predicate then complete', () => { 22 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5}; 23 | const source = cold('(abcde|)', values); 24 | const example = source.first(num => num === 5); 25 | const expected = '(e|)'; 26 | 27 | expectObservable(example).toBe(expected, values) 28 | }); 29 | }); 30 | 31 | describe('Example 3 - Using optional projection function', () => { 32 | it('should emit the result of the projection function, given the first value', () => { 33 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 'First even: 2 is at index: 1'}; 34 | const source = cold('(abcde|)', values); 35 | const example = source.first(num => num % 2 === 0, 36 | (result, index) => `First even: ${result} is at index: ${index}`); 37 | const expected = '(f|)'; 38 | 39 | expectObservable(example).toBe(expected, values) 40 | }); 41 | }); 42 | 43 | describe('Example 4 - Utilizing default value', () => { 44 | it('should emit the default value when source completes and no values pass predicate', () => { 45 | const values = {a: 1, b: 2, c: 3, d: 4, e: 5, f: 'Nothing'}; 46 | const source = cold('(abcde|)', values); 47 | const example = source.first(val => val > 5, val => `Value: ${val}`, 'Nothing'); 48 | const expected = '(f|)'; 49 | 50 | expectObservable(example).toBe(expected, values) 51 | }); 52 | }); 53 | }); -------------------------------------------------------------------------------- /operators/specs/helpers/marble-testing.ts: -------------------------------------------------------------------------------- 1 | declare var global, expect; 2 | 3 | function hot() { 4 | if (!global.rxTestScheduler) { 5 | throw 'tried to use hot() in async test'; 6 | } 7 | return global.rxTestScheduler.createHotObservable.apply(global.rxTestScheduler, arguments); 8 | } 9 | 10 | function cold() { 11 | if (!global.rxTestScheduler) { 12 | throw 'tried to use cold() in async test'; 13 | } 14 | return global.rxTestScheduler.createColdObservable.apply(global.rxTestScheduler, arguments); 15 | } 16 | 17 | function expectObservable() { 18 | if (!global.rxTestScheduler) { 19 | throw 'tried to use expectObservable() in async test'; 20 | } 21 | return global.rxTestScheduler.expectObservable.apply(global.rxTestScheduler, arguments); 22 | } 23 | 24 | function expectSubscriptions() { 25 | if (!global.rxTestScheduler) { 26 | throw 'tried to use expectSubscriptions() in async test'; 27 | } 28 | return global.rxTestScheduler.expectSubscriptions.apply(global.rxTestScheduler, arguments); 29 | } 30 | 31 | function assertDeepEqual(actual, expected) { 32 | ( expect(actual)).toDeepEqual(expected); 33 | } 34 | 35 | export default { 36 | hot: hot, 37 | cold: cold, 38 | expectObservable: expectObservable, 39 | expectSubscriptions: expectSubscriptions, 40 | assertDeepEqual: assertDeepEqual 41 | }; -------------------------------------------------------------------------------- /operators/specs/helpers/test-helper.ts: -------------------------------------------------------------------------------- 1 | declare var global, require, beforeEach, afterEach, jasmine, Symbol; 2 | 3 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; 4 | 5 | const isEqual = require('lodash.isequal'); 6 | 7 | const root = require('rxjs/util/root').root; 8 | import {TestScheduler} from 'rxjs/testing/TestScheduler'; 9 | 10 | import marbleHelpers from './marble-testing'; 11 | 12 | global.rxTestScheduler = null; 13 | global.cold = marbleHelpers.cold; 14 | global.hot = marbleHelpers.hot; 15 | global.expectObservable = marbleHelpers.expectObservable; 16 | global.expectSubscriptions = marbleHelpers.expectSubscriptions; 17 | 18 | const assertDeepEqual = marbleHelpers.assertDeepEqual; 19 | 20 | const glit = global.it; 21 | 22 | global.it = function(description, cb, timeout) { 23 | if (cb.length === 0) { 24 | glit(description, function() { 25 | global.rxTestScheduler = new TestScheduler(assertDeepEqual); 26 | cb(); 27 | global.rxTestScheduler.flush(); 28 | }); 29 | } else { 30 | glit.apply(this, arguments); 31 | } 32 | }; 33 | 34 | global.it.asDiagram = function() { 35 | return global.it; 36 | }; 37 | 38 | const glfit = global.fit; 39 | 40 | global.fit = function(description, cb, timeout) { 41 | if (cb.length === 0) { 42 | glfit(description, function() { 43 | global.rxTestScheduler = new TestScheduler(assertDeepEqual); 44 | cb(); 45 | global.rxTestScheduler.flush(); 46 | }); 47 | } else { 48 | glfit.apply(this, arguments); 49 | } 50 | }; 51 | 52 | function stringify(x) { 53 | return JSON.stringify(x, function(key, value) { 54 | if (Array.isArray(value)) { 55 | return '[' + value 56 | .map(function(i) { 57 | return '\n\t' + stringify(i); 58 | }) + '\n]'; 59 | } 60 | return value; 61 | }) 62 | .replace(/\\"/g, '"') 63 | .replace(/\\t/g, '\t') 64 | .replace(/\\n/g, '\n'); 65 | } 66 | 67 | beforeEach(function() { 68 | jasmine.addMatchers({ 69 | toDeepEqual: function(util, customEqualityTesters) { 70 | return { 71 | compare: function(actual, expected) { 72 | let result: any = { pass: isEqual(actual, expected) }; 73 | 74 | if (!result.pass && Array.isArray(actual) && Array.isArray(expected)) { 75 | result.message = 'Expected \n'; 76 | actual.forEach(function(x) { 77 | result.message += stringify(x) + '\n'; 78 | }); 79 | result.message += '\nto deep equal \n'; 80 | expected.forEach(function(x) { 81 | result.message += stringify(x) + '\n'; 82 | }); 83 | } 84 | 85 | return result; 86 | } 87 | }; 88 | } 89 | }); 90 | }); 91 | 92 | afterEach(function() { 93 | global.rxTestScheduler = null; 94 | }); 95 | 96 | (function() { 97 | Object.defineProperty(Error.prototype, 'toJSON', { 98 | value: function() { 99 | let alt = {}; 100 | 101 | Object.getOwnPropertyNames(this).forEach(function(key) { 102 | if (key !== 'stack') { 103 | alt[key] = this[key]; 104 | } 105 | }, this); 106 | return alt; 107 | }, 108 | configurable: true 109 | }); 110 | 111 | global.__root__ = root; 112 | })(); 113 | 114 | global.lowerCaseO = function lowerCaseO() { 115 | const values = [].slice.apply(arguments); 116 | 117 | const o = { 118 | subscribe: function(observer) { 119 | values.forEach(function(v) { 120 | observer.next(v); 121 | }); 122 | observer.complete(); 123 | } 124 | }; 125 | 126 | o[(Symbol).observable] = function() { 127 | return this; 128 | }; 129 | 130 | return o; 131 | }; -------------------------------------------------------------------------------- /operators/transformation/README.md: -------------------------------------------------------------------------------- 1 | # Transformation Operators 2 | 3 | Transforming values as they pass through the operator chain is a common task. These operators provide transformation techniques 4 | for nearly any use-case you will encounter. 5 | 6 | ## Contents 7 | * [buffer](buffer.md) 8 | * [bufferCount](buffercount.md) 9 | * [bufferTime](buffertime.md) :star: 10 | * [bufferToggle](buffertoggle.md) 11 | * [bufferWhen](bufferwhen.md) 12 | * [concatMap](concatmap.md) :star: 13 | * [concatMapTo](concatmapto.md) 14 | * [exhaustMap](exhaustmap.md) 15 | * [expand](expand.md) 16 | * [groupBy](groupby.md) 17 | * [map](map.md) :star: 18 | * [mapTo](mapto.md) 19 | * [mergeMap](mergemap.md) :star: 20 | * [partition](partition.md) 21 | * [pluck](pluck.md) 22 | * [scan](scan.md) :star: 23 | * [switchMap](switchmap.md) :star: 24 | * [window](window.md) 25 | * [windowCount](windowcount.md) 26 | * [windowTime](windowtime.md) 27 | * [windowToggle](windowtoggle.md) 28 | * [windowWhen](windowwhen.md) 29 | 30 | :star: - *commonly used* -------------------------------------------------------------------------------- /operators/transformation/buffer.md: -------------------------------------------------------------------------------- 1 | # buffer 2 | #### 연산자(operator) 정의: `buffer(closingNotifier: Observable): Observable` 3 | 4 | ## Collect output values until provided observable emits, emit as array. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Buffer until document click 9 | 10 | ( [jsBin](http://jsbin.com/fazimarajo/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/7451s67k/) ) 11 | 12 | ```js 13 | //Create an observable that emits a value every second 14 | const myInterval = Rx.Observable.interval(1000); 15 | //Create an observable that emits every time document is clicked 16 | const bufferBy = Rx.Observable.fromEvent(document, 'click'); 17 | /* 18 | Collect all values emitted by our interval observable until we click document. This will cause the bufferBy Observable to emit a value, satisfying the buffer. Pass us all collected values since last buffer as an array. 19 | */ 20 | const myBufferedInterval = myInterval.buffer(bufferBy); 21 | //Print values to console 22 | //ex. output: [1,2,3] ... [4,5,6,7,8] 23 | const subscribe = myBufferedInterval.subscribe(val => console.log(' Buffered Values:', val)); 24 | ``` 25 | 26 | 27 | ### Additional Resources 28 | * [buffer](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-buffer) :newspaper: - Official docs 29 | * [Transformation operator: buffer](https://egghead.io/lessons/rxjs-transformation-operator-buffer?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 30 | 31 | --- 32 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/buffer.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/buffer.ts) 33 | -------------------------------------------------------------------------------- /operators/transformation/buffercount.md: -------------------------------------------------------------------------------- 1 | # bufferCount 2 | #### 연산자(operator) 정의: `bufferCount(bufferSize: number, startBufferEvery: number = null): Observable` 3 | 4 | ## Collect emitted values until provided number is fulfilled, emit as array. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Collect buffer and emit after specified number of values 9 | 10 | ( [jsBin](http://jsbin.com/suveqaromu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ky9myc5b/) ) 11 | 12 | ```js 13 | //Create an observable that emits a value every second 14 | const source = Rx.Observable.interval(1000); 15 | //After three values are emitted, pass on as an array of buffered values 16 | const bufferThree = source.bufferCount(3); 17 | //Print values to console 18 | //ex. output [0,1,2]...[3,4,5] 19 | const subscribe = bufferThree.subscribe(val => console.log('Buffered Values:', val)); 20 | ``` 21 | 22 | ##### Example 2: Overlapping buffers 23 | 24 | ( [jsBin](http://jsbin.com/kiloxiraya/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3c67qcz1/) ) 25 | 26 | ```js 27 | //Create an observable that emits a value every second 28 | const source = Rx.Observable.interval(1000); 29 | /* 30 | bufferCount also takes second argument, when to start the next buffer 31 | for instance, if we have a bufferCount of 3 but second argument (startBufferEvery) of 1: 32 | 1st interval value: 33 | buffer 1: [0] 34 | 2nd interval value: 35 | buffer 1: [0,1] 36 | buffer 2: [1] 37 | 3rd interval value: 38 | buffer 1: [0,1,2] Buffer of 3, emit buffer 39 | buffer 2: [1,2] 40 | buffer 3: [2] 41 | 4th interval value: 42 | buffer 2: [1,2,3] Buffer of 3, emit buffer 43 | buffer 3: [2, 3] 44 | buffer 4: [3] 45 | */ 46 | const bufferEveryOne = source.bufferCount(3,1); 47 | //Print values to console 48 | const subscribe = bufferEveryOne.subscribe(val => console.log('Start Buffer Every 1:', val)); 49 | ``` 50 | 51 | 52 | ### Additional Resources 53 | * [bufferCount](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-bufferCount) :newspaper: - Official docs 54 | 55 | --- 56 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferCount.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferCount.ts) 57 | -------------------------------------------------------------------------------- /operators/transformation/buffertime.md: -------------------------------------------------------------------------------- 1 | # bufferTime 2 | #### 연산자(operator) 정의: `bufferTime(bufferTimeSpan: number, bufferCreationInterval: number, scheduler: Scheduler): Observable` 3 | 4 | ## Collect emitted values until provided time has passed, emit as array. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Buffer for 2 seconds 9 | 10 | ( [jsBin](http://jsbin.com/bafakiyife/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/vx7vwg01/) ) 11 | 12 | ```js 13 | //Create an observable that emits a value every 500ms 14 | const source = Rx.Observable.interval(500); 15 | //After 2 seconds have passed, emit buffered values as an array 16 | const example = source.bufferTime(2000); 17 | //Print values to console 18 | //ex. output [0,1,2]...[3,4,5,6] 19 | const subscribe = example.subscribe(val => console.log('Buffered with Time:', val)); 20 | ``` 21 | 22 | ##### Example 2: Multiple active buffers 23 | 24 | ( [jsBin](http://jsbin.com/tadiwiniri/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/7k4ygj1x/) ) 25 | 26 | ```js 27 | //Create an observable that emits a value every 500ms 28 | const source = Rx.Observable.interval(500); 29 | /* 30 | bufferTime also takes second argument, when to start the next buffer (time in ms) 31 | for instance, if we have a bufferTime of 2 seconds but second argument (bufferCreationInterval) of 1 second: 32 | ex. output: [0,1,2]...[1,2,3,4,5]...[3,4,5,6,7] 33 | */ 34 | const example = source.bufferTime(2000,1000); 35 | //Print values to console 36 | const subscribe = example.subscribe(val => console.log('Start Buffer Every 1s:', val)); 37 | ``` 38 | 39 | 40 | ### Additional Resources 41 | * [bufferTime](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-bufferTime) :newspaper: - Official docs 42 | 43 | --- 44 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferTime.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferTime.ts) 45 | -------------------------------------------------------------------------------- /operators/transformation/buffertoggle.md: -------------------------------------------------------------------------------- 1 | # bufferToggle 2 | #### 연산자(operator) 정의: `bufferToggle(openings: Observable, closingSelector: Function): Observable` 3 | 4 | ## Toggle on to catch emitted values from source, toggle off to emit buffered values as array. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Toggle buffer on and off at interval 9 | 10 | ( [jsBin](http://jsbin.com/relavezugo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6ad3w3wf/) ) 11 | 12 | ```js 13 | //emit value every second 14 | const sourceInterval = Rx.Observable.interval(1000); 15 | //start first buffer after 5s, and every 5s after 16 | const startInterval = Rx.Observable.interval(5000); 17 | //emit value after 3s, closing corresponding buffer 18 | const closingInterval = val => { 19 | console.log(`Value ${val} emitted, starting buffer! Closing in 3s!`) 20 | return Rx.Observable.interval(3000); 21 | } 22 | //every 5s a new buffer will start, collecting emitted values for 3s then emitting buffered values 23 | const bufferToggleInterval = sourceInterval.bufferToggle(startInterval, closingInterval); 24 | //log to console 25 | //ex. emitted buffers [4,5,6]...[9,10,11] 26 | const subscribe = bufferToggleInterval.subscribe(val => console.log('Emitted Buffer:', val)); 27 | ``` 28 | 29 | 30 | ### Additional Resources 31 | * [bufferToggle](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-bufferToggle) :newspaper: - Official docs 32 | 33 | --- 34 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferToggle.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferToggle.ts) 35 | -------------------------------------------------------------------------------- /operators/transformation/bufferwhen.md: -------------------------------------------------------------------------------- 1 | # bufferWhen 2 | #### 연산자(operator) 정의: `bufferWhen(closingSelector: function): Observable` 3 | 4 | ## Collect all values until closing selector emits, emit buffered values. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Emit buffer based on interval 9 | 10 | ( [jsBin](http://jsbin.com/vugerupube/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/nr9agfuL/) ) 11 | 12 | ```js 13 | //emit value every 1 second 14 | const oneSecondInterval = Rx.Observable.interval(1000); 15 | //return an observable that emits value every 5 seconds 16 | const fiveSecondInterval = () => Rx.Observable.interval(5000); 17 | //every five seconds, emit buffered values 18 | const bufferWhenExample = oneSecondInterval.bufferWhen(fiveSecondInterval); 19 | //log values 20 | //ex. output: [0,1,2,3]...[4,5,6,7,8] 21 | const subscribe = bufferWhenExample.subscribe(val => console.log('Emitted Buffer: ', val)); 22 | ``` 23 | 24 | 25 | ### Additional Resources 26 | * [bufferWhen](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-bufferWhen) :newspaper: - Official docs 27 | 28 | --- 29 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferWhen.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/bufferWhen.ts) 30 | -------------------------------------------------------------------------------- /operators/transformation/concatmap.md: -------------------------------------------------------------------------------- 1 | # concatMap 2 | #### 연산자(operator) 정의: `concatMap(project: function, resultSelector: function): Observable` 3 | 4 | ## Map values to inner observable, subscribe and emit in order. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Map to inner observable 9 | 10 | ( [jsBin](http://jsbin.com/powivemaxu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/y3yx666r/) ) 11 | 12 | ```js 13 | //emit 'Hello' and 'Goodbye' 14 | const source = Rx.Observable.of('Hello', 'Goodbye'); 15 | // map value from source into inner observable, when complete emit result and move to next 16 | const example = source.concatMap(val => Rx.Observable.of(`${val} World!`)); 17 | //output: 'Example One: 'Hello World', Example One: 'Goodbye World' 18 | const subscribe = example 19 | .subscribe(val => console.log('Example One:', val)); 20 | ``` 21 | 22 | ##### Example 2: Map to promise 23 | 24 | ( [jsBin](http://jsbin.com/celixodeba/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/Lym33L97//) ) 25 | 26 | 27 | ```js 28 | //emit 'Hello' and 'Goodbye' 29 | const source = Rx.Observable.of('Hello', 'Goodbye'); 30 | //example with promise 31 | const examplePromise = val => new Promise(resolve => resolve(`${val} World!`)); 32 | // map value from source into inner observable, when complete emit result and move to next 33 | const example = source.concatMap(val => examplePromise(val)) 34 | //output: 'Example w/ Promise: 'Hello World', Example w/ Promise: 'Goodbye World' 35 | const subscribe = example.subscribe(val => console.log('Example w/ Promise:', val)); 36 | ``` 37 | 38 | ##### Example 3: Supplying a projection function 39 | 40 | ( [jsBin](http://jsbin.com/vihacewozo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5sr5zzgy/) ) 41 | 42 | ```js 43 | //emit 'Hello' and 'Goodbye' 44 | const source = Rx.Observable.of('Hello', 'Goodbye'); 45 | //example with promise 46 | const examplePromise = val => new Promise(resolve => resolve(`${val} World!`)); 47 | //result of first param passed to second param selector function before being returned 48 | const example = source.concatMap(val => examplePromise(val), result => `${result} w/ selector!`); 49 | //output: 'Example w/ Selector: 'Hello w/ Selector', Example w/ Selector: 'Goodbye w/ Selector' 50 | const subscribe = example.subscribe(val => console.log('Example w/ Selector:', val)); 51 | ``` 52 | 53 | ##### Example 4: Illustrating difference between concatMap and mergeMap 54 | 55 | ( [jsBin](http://jsbin.com/kiwuvamafo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3xd74d89/) ) 56 | 57 | ```js 58 | const concatMapSub = Rx.Observable.of(2000, 1000) 59 | .concatMap(v => Rx.Observable.of(v).delay(v)) 60 | // concatMap: 2000, concatMap: 1000 61 | .subscribe(v => console.log('concatMap:', v)) 62 | 63 | const mergeMapSub = Rx.Observable.of(2000, 1000) 64 | .mergeMap(v => Rx.Observable.of(v).delay(v)) 65 | // mergeMap: 1000, mergeMap: 2000 66 | .subscribe(v => console.log('mergeMap:', v)) 67 | ``` 68 | 69 | 70 | ### Additional Resources 71 | * [concatMap](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concatMap) :newspaper: - Official docs 72 | * [Use RxJS concatMap to map and concat higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-concatmap-to-map-and-concat-high-order-observables?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 73 | 74 | --- 75 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatMap.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatMap.ts) 76 | -------------------------------------------------------------------------------- /operators/transformation/concatmapto.md: -------------------------------------------------------------------------------- 1 | # concatMapTo 2 | #### 연산자(operator) 정의: `concatMapTo(observable: Observable, resultSelector: function): Observable` 3 | 4 | ## Subscribe to provided observable when previous completes, emit values. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Map to basic observable 9 | 10 | ( [jsBin](http://jsbin.com/telovuhupa/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/La0bam0u/) ) 11 | 12 | ```js 13 | //emit value every 2 seconds 14 | const interval = Rx.Observable.interval(2000); 15 | const message = Rx.Observable.of('Second(s) elapsed!'); 16 | //when interval emits, subscribe to message until complete, merge for result 17 | const example = interval.concatMapTo(message, (time, msg) => `${time} ${msg}`); 18 | //log values 19 | //output: '0 Second(s) elapsed', '1 Second(s) elapsed' 20 | const subscribe = example.subscribe(val => console.log(val)); 21 | ``` 22 | 23 | ##### Example 2: Map to observable that emits at slower pace 24 | 25 | ( [jsBin](http://jsbin.com/fogefebisu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/s19wtscb/) ) 26 | 27 | ```js 28 | //emit value every 2 seconds 29 | const interval = Rx.Observable.interval(2000); 30 | //emit value every second for 5 seconds 31 | const source = Rx.Observable.interval(1000).take(5); 32 | /* 33 | ***Be Careful***: In situations like this where the source emits at a faster pace 34 | than the inner observable completes, memory issues can arise. 35 | (interval emits every 1 second, basicTimer completes every 5) 36 | */ 37 | //basicTimer will complete after 5 seconds, emitting 0,1,2,3,4 38 | const example = interval 39 | .concatMapTo(source, 40 | (firstInterval, secondInterval) => `${firstInterval} ${secondInterval}` 41 | ); 42 | /* 43 | output: 0 0 44 | 0 1 45 | 0 2 46 | 0 3 47 | 0 4 48 | 1 0 49 | 1 1 50 | continued... 51 | 52 | */ 53 | const subscribe = example.subscribe(val => console.log(val)); 54 | ``` 55 | 56 | 57 | ### Additional Resources 58 | * [concatMapTo](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-concatMapTo) :newspaper: - Official docs 59 | 60 | --- 61 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatMapTo.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/concatMapTo.ts) 62 | -------------------------------------------------------------------------------- /operators/transformation/exhaustmap.md: -------------------------------------------------------------------------------- 1 | # exhaustMap 2 | #### 연산자(operator) 정의: `exhaustMap(project: function, resultSelector: function): Observable` 3 | 4 | ## Map to inner observable, ignore other values until that observable completes. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: exhaustMap with interval 9 | 10 | ( [jsBin](http://jsbin.com/woposeqobo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/9ovzapp9/) ) 11 | 12 | ```js 13 | const interval = Rx.Observable.interval(1000); 14 | const delayedInterval = interval.delay(10).take(4); 15 | 16 | const exhaustSub = Rx.Observable 17 | .merge( 18 | // delay 10ms, then start interval emitting 4 values 19 | delayedInterval, 20 | // emit immediately 21 | Rx.Observable.of(true) 22 | ) 23 | /* 24 | * The first emitted value (of(true)) will be mapped 25 | * to an interval observable emitting 1 value every 26 | * second, completing after 5. 27 | * Because the emissions from the delayed interval 28 | * fall while this observable is still active they will be ignored. 29 | * 30 | * Contrast this with concatMap which would queue, 31 | * switchMap which would switch to a new inner observable each emission, 32 | * and mergeMap which would maintain a new subscription for each emitted value. 33 | */ 34 | .exhaustMap(_ => interval.take(5)) 35 | // output: 0, 1, 2, 3, 4 36 | .subscribe(val => console.log(val)) 37 | ``` 38 | 39 | 40 | ##### Example 2: Another exhaustMap with interval 41 | 42 | ( [jsBin](http://jsbin.com/fizuduzuti/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/5ck8yg5k/3/) ) 43 | 44 | ```js 45 | const firstInterval = Rx.Observable.interval(1000).take(10); 46 | const secondInterval = Rx.Observable.interval(1000).take(2); 47 | 48 | const exhaustSub = firstInterval 49 | .do(i => console.log(`Emission of first interval: ${i}`)) 50 | .exhaustMap(f => secondInterval) 51 | /* 52 | When we subscribed to the first interval, it starts to emit a values (startinng 0). 53 | This value is mapped to the second interval which then begins to emit (starting 0). 54 | While the second interval is active, values from the first interval are ignored. 55 | We can see this when firstInterval emits number 3,6, and so on... 56 | 57 | Output: 58 | Emission of first interval: 0 59 | 0 60 | 1 61 | Emission of first interval: 3 62 | 0 63 | 1 64 | Emission of first interval: 6 65 | 0 66 | 1 67 | Emission of first interval: 9 68 | 0 69 | 1 70 | */ 71 | .subscribe(s => console.log(s)); 72 | ``` 73 | 74 | 75 | ### Additional Resources 76 | * [exhaustMap](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-exhaustMap) :newspaper: - Official docs 77 | 78 | --- 79 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/exhaustMap.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/exhaustMap.ts) 80 | -------------------------------------------------------------------------------- /operators/transformation/expand.md: -------------------------------------------------------------------------------- 1 | # expand 2 | #### 연산자(operator) 정의: `expand(project: function, concurrent: number, scheduler: Scheduler): Observable` 3 | 4 | ## Recursively call provided function. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Add one for each invocation 9 | 10 | ( [jsBin](http://jsbin.com/fuxocepazi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/nu4apbLt/) ) 11 | 12 | ```js 13 | //emit 2 14 | const source = Rx.Observable.of(2); 15 | const example = source 16 | //recursively call supplied function 17 | .expand(val => { 18 | //2,3,4,5,6 19 | console.log(`Passed value: ${val}`); 20 | //3,4,5,6 21 | return Rx.Observable.of(1 + val); 22 | }) 23 | //call 5 times 24 | .take(5); 25 | /* 26 | "RESULT: 2" 27 | "Passed value: 2" 28 | "RESULT: 3" 29 | "Passed value: 3" 30 | "RESULT: 4" 31 | "Passed value: 4" 32 | "RESULT: 5" 33 | "Passed value: 5" 34 | "RESULT: 6" 35 | "Passed value: 6" 36 | */ 37 | //output: 2,3,4,5,6 38 | const subscribe = example.subscribe(val => console.log(`RESULT: ${val}`)); 39 | ``` 40 | 41 | 42 | ### Additional Resources 43 | * [expand](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-expand) :newspaper: - Official docs 44 | 45 | --- 46 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/expand.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/expand.ts) 47 | -------------------------------------------------------------------------------- /operators/transformation/groupby.md: -------------------------------------------------------------------------------- 1 | # groupBy 2 | #### 연산자(operator) 정의: `groupBy(keySelector: Function, elementSelector: Function): Observable` 3 | 4 | ## Group into observables based on provided value. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Group by property 9 | 10 | ( [jsBin](http://jsbin.com/zibomoluru/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/utncxxvf/) ) 11 | 12 | ```js 13 | const people = [{name: 'Sue', age:25},{name: 'Joe', age: 30},{name: 'Frank', age: 25}, {name: 'Sarah', age: 35}]; 14 | //emit each person 15 | const source = Rx.Observable.from(people); 16 | //group by age 17 | const example = source 18 | .groupBy(person => person.age) 19 | //return as array of each group 20 | .flatMap(group => group.reduce((acc, curr) => [...acc, curr], [])) 21 | /* 22 | output: 23 | [{age: 25, name: "Sue"},{age: 25, name: "Frank"}] 24 | [{age: 30, name: "Joe"}] 25 | [{age: 35, name: "Sarah"}] 26 | */ 27 | const subscribe = example.subscribe(val => console.log(val)); 28 | ``` 29 | 30 | 31 | ### Additional Resources 32 | * [groupBy](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-groupBy) :newspaper: - Official docs 33 | * [Group higher order observables with RxJS groupBy](https://egghead.io/lessons/rxjs-group-higher-order-observables-with-rxjs-groupby?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 34 | * [Use groupBy in real RxJS applications](https://egghead.io/lessons/rxjs-use-groupby-in-real-rxjs-applications?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 35 | 36 | --- 37 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/groupBy.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/groupBy.ts) 38 | -------------------------------------------------------------------------------- /operators/transformation/map.md: -------------------------------------------------------------------------------- 1 | # map 2 | #### 연산자(operator) 정의: `map(project: Function, thisArg: any): Observable` 3 | 4 | ## Apply projection with each value from source. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Add 10 to each number 9 | 10 | ( [jsBin](http://jsbin.com/padasukano/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/yd38awLa/) ) 11 | 12 | ```js 13 | //emit (1,2,3,4,5) 14 | const source = Rx.Observable.from([1,2,3,4,5]); 15 | //add 10 to each value 16 | const example = source.map(val => val + 10); 17 | //output: 11,12,13,14,15 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ##### Example 2: Map to single property 22 | 23 | ( [jsBin](http://jsbin.com/detozumale/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/tdLd5tgc/) ) 24 | 25 | ```js 26 | //emit ({name: 'Joe', age: 30}, {name: 'Frank', age: 20},{name: 'Ryan', age: 50}) 27 | const source = Rx.Observable.from([{name: 'Joe', age: 30}, {name: 'Frank', age: 20},{name: 'Ryan', age: 50}]); 28 | //grab each persons name 29 | const example = source.map(person => person.name); 30 | //output: "Joe","Frank","Ryan" 31 | const subscribe = example.subscribe(val => console.log(val)); 32 | ``` 33 | 34 | ### Related Recipes 35 | * [Smart Counter](../../recipes/smartcounter.md) 36 | 37 | ### Additional Resources 38 | * [map](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-map) :newspaper: - Official docs 39 | * [map vs flatMap](https://egghead.io/lessons/rxjs-rxjs-map-vs-flatmap) :video_camera: - Ben Lesh 40 | * [Transformation operator: map and mapTo](https://egghead.io/lessons/rxjs-transformation-operator-map-and-mapto?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 41 | 42 | --- 43 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/map.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/map.ts) 44 | -------------------------------------------------------------------------------- /operators/transformation/mapto.md: -------------------------------------------------------------------------------- 1 | # mapTo 2 | #### 연산자(operator) 정의: `mapTo(value: any): Observable` 3 | 4 | ## Map emissions to constant value. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Map every emission to string 9 | 10 | ( [jsBin](http://jsbin.com/qujolenili/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/4ojq56ng/) ) 11 | 12 | ```js 13 | //emit value every two seconds 14 | const source = Rx.Observable.interval(2000); 15 | //map all emissions to one value 16 | const example = source.mapTo('HELLO WORLD!'); 17 | //output: 'HELLO WORLD!'...'HELLO WORLD!'...'HELLO WORLD!'... 18 | const subscribe = example.subscribe(val => console.log(val)); 19 | ``` 20 | 21 | ##### Example 2: Mapping clicks to string 22 | 23 | ( [jsBin](http://jsbin.com/xaheciwara/1/edit?js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/52fqL4nn/) ) 24 | 25 | ```js 26 | //emit every click on document 27 | const source = Rx.Observable.fromEvent(document, 'click'); 28 | //map all emissions to one value 29 | const example = source.mapTo('GOODBYE WORLD!'); 30 | //output: (click)'GOODBYE WORLD!'... 31 | const subscribe = example.subscribe(val => console.log(val)); 32 | ``` 33 | 34 | ### Related Recipes 35 | * [Smart Counter](../../recipes/smartcounter.md) 36 | 37 | ### Additional Resources 38 | * [mapTo](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mapTo) :newspaper: - Official docs 39 | * [Changing behavior with mapTo](https://egghead.io/lessons/rxjs-changing-behavior-with-mapto?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 40 | * [Transformation operator: map and mapTo](https://egghead.io/lessons/rxjs-transformation-operator-map-and-mapto?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 41 | 42 | --- 43 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/mapTo.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/mapTo.ts) 44 | -------------------------------------------------------------------------------- /operators/transformation/mergemap.md: -------------------------------------------------------------------------------- 1 | # mergeMap 2 | #### 연산자(operator) 정의: `mergeMap(project: function: Observable, resultSelector: function: any, concurrent: number): Observable` 3 | 4 | ## Map to observable, emit values. 5 | 6 | --- 7 | :bulb: flatMap is an alias for mergeMap! 8 | 9 | :bulb: If only one inner subscription should be active at a time, try [`switchMap`](switchmap.md)! 10 | 11 | :bulb: If the order of emission and subscription of inner observables is important, try [`concatMap`](concatmap.md)! 12 | 13 | --- 14 | 15 | ### Examples 16 | 17 | ##### Example 1: mergeMap with observable 18 | 19 | ( [jsBin](http://jsbin.com/mojurubana/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/41awjgda/) ) 20 | 21 | ```js 22 | //emit 'Hello' 23 | const source = Rx.Observable.of('Hello'); 24 | //map to inner observable and flatten 25 | const example = source.mergeMap(val => Rx.Observable.of(`${val} World!`)); 26 | //output: 'Hello World!' 27 | const subscribe = example.subscribe(val => console.log(val)); 28 | ``` 29 | 30 | ##### Example 2: mergeMap with promise 31 | 32 | ( [jsBin](http://jsbin.com/vuhecorana/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/o9kxpvsv/) ) 33 | 34 | ```js 35 | //emit 'Hello' 36 | const source = Rx.Observable.of('Hello'); 37 | //mergeMap also emits result of promise 38 | const myPromise = val => new Promise(resolve => resolve(`${val} World From Promise!`)); 39 | //map to promise and emit result 40 | const example = source.mergeMap(val => myPromise(val)); 41 | //output: 'Hello World From Promise' 42 | const subscribe = example.subscribe(val => console.log(val)); 43 | ``` 44 | 45 | ##### Example 3: mergeMap with `resultSelector` 46 | 47 | ( [jsBin](http://jsbin.com/wajokocage/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/zu9a6vr4/) ) 48 | 49 | ```js 50 | /* 51 | you can also supply a second argument which receives the source value and emitted 52 | value of inner observable or promise 53 | */ 54 | //emit 'Hello' 55 | const source = Rx.Observable.of('Hello'); 56 | //mergeMap also emits result of promise 57 | const myPromise = val => new Promise(resolve => resolve(`${val} World From Promise!`)); 58 | const example = source 59 | .mergeMap(val => myPromise(val), 60 | (valueFromSource, valueFromPromise) => { 61 | return `Source: ${valueFromSource}, Promise: ${valueFromPromise}`; 62 | }); 63 | //output: "Source: Hello, Promise: Hello World From Promise!" 64 | const subscribe = example.subscribe(val => console.log(val)); 65 | ``` 66 | 67 | ##### Example 4: mergeMap with concurrent value 68 | 69 | ( [jsBin](http://jsbin.com/qaqucuwise/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/2rmLxpyz/) ) 70 | 71 | ```js 72 | //emit value every 1s 73 | const source = Rx.Observable.interval(1000); 74 | 75 | const example = source.mergeMap( 76 | //project 77 | val => Rx.Observable.interval(5000).take(2), 78 | //resultSelector 79 | (oVal, iVal, oIndex, iIndex) => [oIndex, oVal, iIndex, iVal], 80 | //concurrent 81 | 2 82 | ); 83 | /* 84 | Output: 85 | [0, 0, 0, 0] <--1st inner observable 86 | [1, 1, 0, 0] <--2nd inner observable 87 | [0, 0, 1, 1] <--1st inner observable 88 | [1, 1, 1, 1] <--2nd inner observable 89 | [2, 2, 0, 0] <--3rd inner observable 90 | [3, 3, 0, 0] <--4th inner observable 91 | */ 92 | const subscribe = example.subscribe(val => console.log(val)); 93 | ``` 94 | 95 | 96 | ### Additional Resources 97 | * [mergeMap](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-mergeMap) :newspaper: - Official docs 98 | * [map vs flatMap](https://egghead.io/lessons/rxjs-rxjs-map-vs-flatmap) :video_camera: - Ben Lesh 99 | * [Async requests and responses in RxJS](https://egghead.io/lessons/rxjs-04-reactive-programming-async-requests-and-responses-in-rxjs) :video_camera: :dollar: - André Staltz 100 | * [Use RxJS mergeMap to map and merge higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-mergemap-to-map-and-merge-high-order-observables?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 101 | * [Use RxJS mergeMap for fine grain custom behavior](https://egghead.io/lessons/rxjs-use-rxjs-mergemap-for-fine-grain-custom-behavior?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 102 | 103 | --- 104 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/mergeMap.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/mergeMap.ts) 105 | -------------------------------------------------------------------------------- /operators/transformation/partition.md: -------------------------------------------------------------------------------- 1 | # partition 2 | #### 연산자(operator) 정의: `partition(predicate: function: boolean, thisArg: any): [Observable, Observable]` 3 | 4 | ## Split one observable into two based on provided predicate. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Split even and odd numbers 9 | 10 | ( [jsBin](http://jsbin.com/hipehexaku/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/q0xo7gvv/) ) 11 | 12 | ```js 13 | const source = Rx.Observable.from([1,2,3,4,5,6]); 14 | //first value is true, second false 15 | const [evens, odds] = source.partition(val => val % 2 === 0); 16 | /* 17 | Output: 18 | "Even: 2" 19 | "Even: 4" 20 | "Even: 6" 21 | "Odd: 1" 22 | "Odd: 3" 23 | "Odd: 5" 24 | */ 25 | const subscribe = Rx.Observable.merge( 26 | evens 27 | .map(val => `Even: ${val}`), 28 | odds 29 | .map(val => `Odd: ${val}`) 30 | ).subscribe(val => console.log(val)); 31 | ``` 32 | 33 | ##### Example 2: Split success and errors 34 | 35 | ( [jsBin](http://jsbin.com/kukuguhuri/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/fe246u5p/) ) 36 | 37 | ```js 38 | const source = Rx.Observable.from([1,2,3,4,5,6]); 39 | //if greater than 3 throw 40 | const example = source 41 | .map(val => { 42 | if(val > 3){ 43 | throw `${val} greater than 3!` 44 | } 45 | return {success: val}; 46 | }) 47 | .catch(val => Rx.Observable.of({error: val})); 48 | //split on success or error 49 | const [success, error] = example.partition(res => res.success) 50 | /* 51 | Output: 52 | "Success! 1" 53 | "Success! 2" 54 | "Success! 3" 55 | "Error! 4 greater than 3!" 56 | */ 57 | const subscribe = Rx.Observable.merge( 58 | success.map(val => `Success! ${val.success}`), 59 | error.map(val => `Error! ${val.error}`) 60 | ).subscribe(val => console.log(val)); 61 | ``` 62 | 63 | 64 | ### Additional Resources 65 | * [partition](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-partition) :newspaper: - Official docs 66 | 67 | --- 68 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/partition.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/partition.ts) 69 | -------------------------------------------------------------------------------- /operators/transformation/pluck.md: -------------------------------------------------------------------------------- 1 | # pluck 2 | #### 연산자(operator) 정의: `pluck(properties: ...args): Observable` 3 | 4 | ## Select properties to emit. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Pluck object property 9 | 10 | ( [jsBin](http://jsbin.com/zokaxiwahe/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/58v9xq0f/) ) 11 | 12 | ```js 13 | const source = Rx.Observable.from([ 14 | {name: 'Joe', age: 30}, 15 | {name: 'Sarah', age:35} 16 | ]); 17 | //grab names 18 | const example = source.pluck('name'); 19 | //output: "Joe", "Sarah" 20 | const subscribe = example.subscribe(val => console.log(val)); 21 | ``` 22 | 23 | ##### Example 2: Pluck nested properties 24 | 25 | ( [jsBin](http://jsbin.com/joqesidugu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/n592m597/) ) 26 | 27 | ```js 28 | const source = Rx.Observable.from([ 29 | {name: 'Joe', age: 30, job: {title: 'Developer', language: 'JavaScript'}}, 30 | //will return undefined when no job is found 31 | {name: 'Sarah', age:35} 32 | ]); 33 | //grab title property under job 34 | const example = source.pluck('job', 'title'); 35 | //output: "Developer" , undefined 36 | const subscribe = example.subscribe(val => console.log(val)); 37 | ``` 38 | 39 | 40 | ### Additional Resources 41 | * [pluck](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-pluck) :newspaper: - Official docs 42 | 43 | --- 44 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/pluck.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/pluck.ts) 45 | -------------------------------------------------------------------------------- /operators/transformation/scan.md: -------------------------------------------------------------------------------- 1 | # scan 2 | #### 연산자(operator) 정의: `scan(accumulator: function, seed: any): Observable` 3 | 4 | ## Reduce over time. 5 | 6 | --- 7 | :bulb: This operator is the core for many RxJS based [Redux](http://redux.js.org) implementations! 8 | 9 | --- 10 | 11 | ### Examples 12 | 13 | ##### Example 1: Sum over time 14 | 15 | ( [jsBin](http://jsbin.com/kozidakose/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/d2g2a2c6/) ) 16 | 17 | ```js 18 | const subject = new Rx.Subject(); 19 | //basic scan example, sum over time starting with zero 20 | const example = subject 21 | .startWith(0) 22 | .scan((acc, curr) => acc + curr); 23 | //log accumulated values 24 | const subscribe = example.subscribe(val => console.log('Accumulated total:', val)); 25 | //next values into subject, adding to the current sum 26 | subject.next(1); //1 27 | subject.next(2); //3 28 | subject.next(3); //6 29 | ``` 30 | 31 | ##### Example 2: Accumulating an object 32 | 33 | ( [jsBin](http://jsbin.com/fusunoguqu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/36rbu38b/) ) 34 | 35 | ```js 36 | const subject = new Rx.Subject(); 37 | //scan example building an object over time 38 | const example = subject.scan((acc, curr) => Object.assign({}, acc, curr), {}); 39 | //log accumulated values 40 | const subscribe = example.subscribe(val => console.log('Accumulated object:', val)); 41 | //next values into subject, adding properties to object 42 | subject.next({name: 'Joe'}); // {name: 'Joe'} 43 | subject.next({age: 30}); // {name: 'Joe', age: 30} 44 | subject.next({favoriteLanguage: 'JavaScript'}); // {name: 'Joe', age: 30, favoriteLanguage: 'JavaScript'} 45 | ``` 46 | 47 | ##### Example 3: Emitting random values from the accumulated array. 48 | 49 | ( [jsBin](http://jsbin.com/mudolideqo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/afjgf4tz/) ) 50 | 51 | ```js 52 | // Accumulate values in an array, emit random values from this array. 53 | const scanObs = Rx.Observable.interval(1000) 54 | .scan((a,c) => a.concat(c), []) 55 | .map(r => r[Math.floor(Math.random()*r.length)]) 56 | .distinctUntilChanged() 57 | .subscribe(console.log); 58 | ``` 59 | 60 | ### Related Recipes 61 | * [Smart Counter](../../recipes/smartcounter.md) 62 | 63 | ### Additional Resources 64 | * [scan](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-scan) :newspaper: - Official docs 65 | * [Aggregating streams with reduce and scan using RxJS](https://egghead.io/lessons/rxjs-aggregating-streams-with-reduce-and-scan-using-rxjs) :video_camera: - Ben Lesh 66 | * [Updating data with scan](https://egghead.io/lessons/rxjs-updating-data-with-scan?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 67 | * [Transformation operator: scan](https://egghead.io/lessons/rxjs-transformation-operator-scan?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 68 | 69 | --- 70 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/scan.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/scan.ts) 71 | -------------------------------------------------------------------------------- /operators/transformation/switchmap.md: -------------------------------------------------------------------------------- 1 | #switchMap 2 | #### 연산자(operator) 정의: ` switchMap(project: function: Observable, resultSelector: function(outerValue, innerValue, outerIndex, innerIndex): any): Observable` 3 | 4 | ## Map to observable, complete previous inner observable, emit values. 5 | 6 | --- 7 | 8 | :bulb: If you would like more than one inner subscription to be maintained, try [`mergeMap`](mergemap.md)! 9 | 10 | :bulb: This operator is generally considered a safer default to [`mergeMap`](mergemap.md)! 11 | 12 | :bulb: This operator can cancel in-flight network requests! 13 | 14 | --- 15 | 16 | ### Examples 17 | 18 | ##### Example 1: Restart interval every 5 seconds 19 | 20 | ( [jsBin](http://jsbin.com/birepuveya/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6pz981gd/) ) 21 | 22 | ```js 23 | //emit immediately, then every 5s 24 | const source = Rx.Observable.timer(0, 5000); 25 | //switch to new inner observable when source emits, emit items that are emitted 26 | const example = source.switchMap(() => Rx.Observable.interval(500)); 27 | //output: 0,1,2,3,4,5,6,7,8,9...0,1,2,3,4,5,6,7,8 28 | const subscribe = example.subscribe(val => console.log(val)); 29 | ``` 30 | 31 | ##### Example 2: Reset on every click 32 | 33 | ( [jsBin](http://jsbin.com/zoruboxogo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/y11v8aqz/) ) 34 | 35 | ```js 36 | //emit every click 37 | const source = Rx.Observable.fromEvent(document, 'click'); 38 | //if another click comes within 3s, message will not be emitted 39 | const example = source.switchMap(val => Rx.Observable.interval(3000).mapTo('Hello, I made it!')); 40 | //(click)...3s...'Hello I made it!'...(click)...2s(click)... 41 | const subscribe = example.subscribe(val => console.log(val)); 42 | ``` 43 | 44 | ##### Example 3: Using a `resultSelector` function 45 | 46 | ( [jsBin](http://jsbin.com/qobapubeze/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/nqfu534y/) ) 47 | 48 | ```js 49 | //emit immediately, then every 5s 50 | const source = Rx.Observable.timer(0, 5000); 51 | //switch to new inner observable when source emits, invoke project function and emit values 52 | const example = source.switchMap(() => Rx.Observable.interval(2000), (outerValue, innerValue, outerIndex, innerIndex) => ({outerValue, innerValue, outerIndex, innerIndex})); 53 | /* 54 | Output: 55 | {outerValue: 0, innerValue: 0, outerIndex: 0, innerIndex: 0} 56 | {outerValue: 0, innerValue: 1, outerIndex: 0, innerIndex: 1} 57 | {outerValue: 1, innerValue: 0, outerIndex: 1, innerIndex: 0} 58 | {outerValue: 1, innerValue: 1, outerIndex: 1, innerIndex: 1} 59 | */ 60 | const subscribe = example.subscribe(val => console.log(val)); 61 | ``` 62 | 63 | ##### Example 4: Countdown timer with switchMap 64 | 65 | ( [jsBin](http://jsbin.com/zahohikaha/1/edit?html,js,console,output) | [jsFiddle](https://jsfiddle.net/btroncone/ww7zg988/1/) ) 66 | 67 | ```js 68 | const countdownSeconds = 60; 69 | const setHTML = id => val => document.getElementById(id).innerHTML = val; 70 | const pauseButton = document.getElementById('pause'); 71 | const resumeButton = document.getElementById('resume'); 72 | const interval$ = Rx.Observable.interval(1000).mapTo(-1); 73 | 74 | const pause$ = Rx.Observable.fromEvent(pauseButton, 'click').mapTo(Rx.Observable.of(false)) 75 | const resume$ = Rx.Observable.fromEvent(resumeButton, 'click').mapTo(interval$); 76 | 77 | const timer$ = Rx.Observable 78 | .merge(pause$, resume$) 79 | .startWith(interval$) 80 | .switchMap(val => val) 81 | // if pause button is clicked stop countdown 82 | .scan((acc, curr) => curr ? curr + acc : acc, countdownSeconds) 83 | .subscribe(setHTML('remaining')); 84 | ``` 85 | 86 | ###### HTML 87 | ```html 88 |

89 | Time remaining: 90 |

91 | 94 | 97 | ``` 98 | 99 | ### Related Recipes 100 | * [Smart Counter](../../recipes/smartcounter.md) 101 | 102 | ### Additional Resources 103 | * [switchMap](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-switchMap) :newspaper: - Official docs 104 | * [Starting a stream with switchMap](https://egghead.io/lessons/rxjs-starting-a-stream-with-switchmap?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 105 | * [Use RxJS switchMap to map and flatten higher order observables](https://egghead.io/lessons/rxjs-use-rxjs-switchmap-to-map-and-flatten-higher-order-observables?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 106 | * [Use switchMap as a safe default to flatten observables in RxJS](https://egghead.io/lessons/rxjs-use-switchmap-as-a-safe-default-to-flatten-observables-in-rxjs?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 107 | 108 | --- 109 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/switchMap.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/switchMap.ts) 110 | -------------------------------------------------------------------------------- /operators/transformation/window.md: -------------------------------------------------------------------------------- 1 | # window 2 | #### 연산자(operator) 정의: `window(windowBoundaries: Observable): Observable` 3 | 4 | ## Observable of values for window of time. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Open window specified by inner observable 9 | 10 | ( [jsBin](http://jsbin.com/jituvajeri/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/rmgghg6d/) ) 11 | 12 | ```js 13 | //emit immediately then every 1s 14 | const source = Rx.Observable.timer(0, 1000); 15 | const example = source 16 | .window(Rx.Observable.interval(3000)) 17 | const count = example.scan((acc, curr) => acc + 1, 0) 18 | /* 19 | "Window 1:" 20 | 0 21 | 1 22 | 2 23 | "Window 2:" 24 | 3 25 | 4 26 | 5 27 | ... 28 | */ 29 | const subscribe = count.subscribe(val => console.log(`Window ${val}:`)); 30 | const subscribeTwo = example.mergeAll().subscribe(val => console.log(val)); 31 | ``` 32 | 33 | 34 | ### Additional Resources 35 | * [window](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-window) :newspaper: - Official docs 36 | * [Split an RxJS observable with window](https://egghead.io/lessons/rxjs-split-an-rxjs-observable-with-window?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 37 | 38 | --- 39 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/window.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/window.ts) 40 | -------------------------------------------------------------------------------- /operators/transformation/windowcount.md: -------------------------------------------------------------------------------- 1 | # windowCount 2 | #### 연산자(operator) 정의: `windowCount(windowSize: number, startWindowEvery: number): Observable` 3 | 4 | ## Observable of values from source, emitted each time provided count is fulfilled. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Start new window every x items emitted 9 | 10 | ( [jsBin](http://jsbin.com/nezuvacexe/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xjgbnqp5/) ) 11 | 12 | ```js 13 | //emit every 1s 14 | const source = Rx.Observable.interval(1000); 15 | const example = source 16 | //start new window every 4 emitted values 17 | .windowCount(4) 18 | .do(() => console.log('NEW WINDOW!')) 19 | 20 | const subscribeTwo = example 21 | //window emits nested observable 22 | .mergeAll() 23 | /* 24 | output: 25 | "NEW WINDOW!" 26 | 0 27 | 1 28 | 2 29 | 3 30 | "NEW WINDOW!" 31 | 4 32 | 5 33 | 6 34 | 7 35 | */ 36 | .subscribe(val => console.log(val)); 37 | ``` 38 | 39 | 40 | ### Additional Resources 41 | * [windowCount](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-windowCount) :newspaper: - Official docs 42 | 43 | --- 44 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowCount.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowCount.ts) 45 | -------------------------------------------------------------------------------- /operators/transformation/windowtime.md: -------------------------------------------------------------------------------- 1 | # windowTime 2 | #### 연산자(operator) 정의: `windowTime(windowTimeSpan: number, windowCreationInterval: number, scheduler: Scheduler): Observable` 3 | 4 | ## Observable of values collected from source for each provided time span. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Open new window every specified duration 9 | 10 | ( [jsBin](http://jsbin.com/mifayacoqo/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/g04b3qeb/) ) 11 | 12 | ```js 13 | //emit immediately then every 1s 14 | const source = Rx.Observable.timer(0,1000); 15 | const example = source 16 | //start new window every 3s 17 | .windowTime(3000) 18 | .do(() => console.log('NEW WINDOW!')) 19 | 20 | const subscribeTwo = example 21 | //window emits nested observable 22 | .mergeAll() 23 | /* 24 | output: 25 | "NEW WINDOW!" 26 | 0 27 | 1 28 | 2 29 | "NEW WINDOW!" 30 | 3 31 | 4 32 | 5 33 | */ 34 | .subscribe(val => console.log(val)); 35 | ``` 36 | 37 | 38 | ### Additional Resources 39 | * [windowTime](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-windowTime) :newspaper: - Official docs 40 | 41 | --- 42 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowTime.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowTime.ts) 43 | -------------------------------------------------------------------------------- /operators/transformation/windowtoggle.md: -------------------------------------------------------------------------------- 1 | # windowToggle 2 | #### 연산자(operator) 정의: `windowToggle(openings: Observable, closingSelector: function(value): Observable): Observable` 3 | 4 | ## Collect and emit observable of values from source between opening and closing emission. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Toggle window at increasing interval 9 | 10 | ( [jsBin](http://jsbin.com/xasofupuka/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/3xmmuzy4/) ) 11 | 12 | ```js 13 | //emit immediately then every 1s 14 | const source = Rx.Observable.timer(0,1000); 15 | //toggle window on every 5 16 | const toggle = Rx.Observable.interval(5000); 17 | const example = source 18 | //turn window on every 5s 19 | .windowToggle(toggle, (val) => Rx.Observable.interval(val * 1000)) 20 | .do(() => console.log('NEW WINDOW!')) 21 | 22 | const subscribeTwo = example 23 | //window emits nested observable 24 | .mergeAll() 25 | /* 26 | output: 27 | "NEW WINDOW!" 28 | 5 29 | "NEW WINDOW!" 30 | 10 31 | 11 32 | "NEW WINDOW!" 33 | 15 34 | 16 35 | "NEW WINDOW!" 36 | 20 37 | 21 38 | 22 39 | */ 40 | .subscribe(val => console.log(val)); 41 | ``` 42 | 43 | 44 | ### Additional Resources 45 | * [windowToggle](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-windowToggle) :newspaper: - Official docs 46 | * [Split an RxJS observable conditionally with windowToggle](https://egghead.io/lessons/rxjs-split-an-rxjs-observable-conditionally-with-windowtoggle?course=use-higher-order-observables-in-rxjs-effectively) :video_camera: :dollar: - André Staltz 47 | 48 | --- 49 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowToggle.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowToggle.ts) 50 | -------------------------------------------------------------------------------- /operators/transformation/windowwhen.md: -------------------------------------------------------------------------------- 1 | # windowWhen 2 | #### 연산자(operator) 정의: `windowWhen(closingSelector: function(): Observable): Observable` 3 | 4 | ## Close window at provided time frame emitting observable of collected values from source. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Open and close window at interval 9 | 10 | ( [jsBin](http://jsbin.com/tuhaposemo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/gnx9fb3h/) ) 11 | 12 | ```js 13 | //emit immediately then every 1s 14 | const source = Rx.Observable.timer(0,1000); 15 | const example = source 16 | //close window every 5s and emit observable of collected values from source 17 | .windowWhen((val) => Rx.Observable.interval(5000)) 18 | .do(() => console.log('NEW WINDOW!')) 19 | 20 | const subscribeTwo = example 21 | //window emits nested observable 22 | .mergeAll() 23 | /* 24 | output: 25 | "NEW WINDOW!" 26 | 0 27 | 1 28 | 2 29 | 3 30 | 4 31 | "NEW WINDOW!" 32 | 5 33 | 6 34 | 7 35 | 8 36 | 9 37 | */ 38 | .subscribe(val => console.log(val)); 39 | ``` 40 | 41 | 42 | ### Additional Resources 43 | * [windowWhen](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-windowWhen) :newspaper: - Official docs 44 | 45 | --- 46 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowWhen.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/windowWhen.ts) 47 | -------------------------------------------------------------------------------- /operators/utility/README.md: -------------------------------------------------------------------------------- 1 | # Utility Operators 2 | 3 | From logging, handling notifications, to setting up schedulers, these operators 4 | provide helpful utilities in your observable toolkit. 5 | 6 | ## Contents 7 | * [do](do.md) :star: 8 | * [delay](delay.md) 9 | * [delayWhen](delaywhen.md) 10 | * [dematerialize](dematerialize.md) 11 | * [let](let.md) 12 | * [materialize](materialize.md) 13 | * [observeOn](observeon.md) 14 | * [toPromise](topromise.md) 15 | 16 | :star: - *commonly used* -------------------------------------------------------------------------------- /operators/utility/delay.md: -------------------------------------------------------------------------------- 1 | # delay 2 | #### 연산자(operator) 정의: `delay(delay: number | Date, scheduler: Scheduler): Observable` 3 | 4 | ## Delay emitted values by given time. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Delay for increasing durations 9 | 10 | ( [jsBin](http://jsbin.com/zebatixije/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/1kxtzcu6/) ) 11 | 12 | ```js 13 | //emit one item 14 | const example = Rx.Observable.of(null); 15 | //delay output of each by an extra second 16 | const message = Rx.Observable.merge( 17 | example.mapTo('Hello'), 18 | example.mapTo('World!').delay(1000), 19 | example.mapTo('Goodbye').delay(2000), 20 | example.mapTo('World!').delay(3000) 21 | ); 22 | //output: 'Hello'...'World!'...'Goodbye'...'World!' 23 | const subscribe = message.subscribe(val => console.log(val)); 24 | ``` 25 | 26 | 27 | ### Additional Resources 28 | * [delay](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-delay) :newspaper: - Official docs 29 | * [Transformation operator: delay and delayWhen](https://egghead.io/lessons/rxjs-transformation-operators-delay-and-delaywhen?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 30 | 31 | --- 32 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/delay.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/delay.ts) 33 | -------------------------------------------------------------------------------- /operators/utility/delaywhen.md: -------------------------------------------------------------------------------- 1 | # delayWhen 2 | #### 연산자(operator) 정의: `delayWhen(selector: Function, sequence: Observable): Observable` 3 | 4 | ## Delay emitted values determined by provided function. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Delay based on observable 9 | 10 | ( [jsBin](http://jsbin.com/topohekuje/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/b057mxkL/) ) 11 | 12 | ```js 13 | //emit value every second 14 | const message = Rx.Observable.interval(1000); 15 | //emit value after five seconds 16 | const delayForFiveSeconds = () => Rx.Observable.timer(5000); 17 | //after 5 seconds, start emitting delayed interval values 18 | const delayWhenExample = message.delayWhen(delayForFiveSeconds); 19 | //log values, delayed for 5 seconds 20 | //ex. output: 5s....1...2...3 21 | const subscribe = delayWhenExample.subscribe(val => console.log(val)); 22 | ``` 23 | 24 | 25 | ### Additional Resources 26 | * [delayWhen](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-delayWhen) :newspaper: - Official docs 27 | * [Transformation operator: delay and delayWhen](https://egghead.io/lessons/rxjs-transformation-operators-delay-and-delaywhen?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 28 | 29 | --- 30 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/delayWhen.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/delayWhen.ts) 31 | -------------------------------------------------------------------------------- /operators/utility/dematerialize.md: -------------------------------------------------------------------------------- 1 | # dematerialize 2 | #### 연산자(operator) 정의: `dematerialize(): Observable` 3 | 4 | ## Turn notification objects into notification values. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Converting notifications to values 9 | 10 | ( [jsBin](http://jsbin.com/vafedocibi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/jw08mouy/) ) 11 | 12 | ```js 13 | //emit next and error notifications 14 | const source = Rx.Observable 15 | .from([ 16 | Rx.Notification.createNext('SUCCESS!'), 17 | Rx.Notification.createError('ERROR!') 18 | ]) 19 | //turn notification objects into notification values 20 | .dematerialize(); 21 | 22 | //output: 'NEXT VALUE: SUCCESS' 'ERROR VALUE: 'ERROR!' 23 | const subscription = source.subscribe({ 24 | next: val => console.log(`NEXT VALUE: ${val}`), 25 | error: val => console.log(`ERROR VALUE: ${val}`) 26 | }); 27 | ``` 28 | 29 | 30 | ### Additional Resources 31 | * [dematerialize](http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-dematerialize) :newspaper: - Official docs 32 | 33 | --- 34 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/demterialize.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/dematerialize.ts) 35 | -------------------------------------------------------------------------------- /operators/utility/do.md: -------------------------------------------------------------------------------- 1 | # do 2 | #### 연산자(operator) 정의: `do(nextOrObserver: function, error: function, complete: function): Observable` 3 | 4 | ## Transparently perform actions or side-effects, such as logging. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Logging with do 9 | 10 | ( [jsBin](http://jsbin.com/jimazuriva/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qtyakorq/) ) 11 | 12 | ```js 13 | const source = Rx.Observable.of(1,2,3,4,5); 14 | //transparently log values from source with 'do' 15 | const example = source 16 | .do(val => console.log(`BEFORE MAP: ${val}`)) 17 | .map(val => val + 10) 18 | .do(val => console.log(`AFTER MAP: ${val}`)); 19 | //'do' does not transform values 20 | //output: 11...12...13...14...15 21 | const subscribe = example.subscribe(val => console.log(val)); 22 | ``` 23 | 24 | 25 | ### Additional Resources 26 | * [do](https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts) :newspaper: - Official docs 27 | * [Logging a stream with do](https://egghead.io/lessons/rxjs-logging-a-stream-with-do?course=step-by-step-async-javascript-with-rxjs) :video_camera: :dollar: - John Linquist 28 | * [Utility operator: do](https://egghead.io/lessons/rxjs-utility-operator-do?course=rxjs-beyond-the-basics-operators-in-depth) :video_camera: :dollar: - André Staltz 29 | 30 | --- 31 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/do.ts) 32 | -------------------------------------------------------------------------------- /operators/utility/let.md: -------------------------------------------------------------------------------- 1 | # let 2 | #### 연산자(operator) 정의: `let(function): Observable` 3 | 4 | ## Let me have the whole observable. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Reusing error handling logic with let 9 | 10 | ( [jsBin](http://jsbin.com/rosuborara/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/qtq1h8vw/) ) 11 | 12 | ```js 13 | // custom error handling logic 14 | const retryThreeTimes = obs => obs.retry(3).catch(_ => Rx.Observable.of('ERROR!')); 15 | const examplePromise = val => new Promise(resolve => resolve(`Complete: ${val}`)); 16 | 17 | //faking request 18 | const subscribe = Rx.Observable 19 | .of('some_url') 20 | .mergeMap(url => examplePromise(url)) 21 | // could reuse error handling logic in multiple places with let 22 | .let(retryThreeTimes) 23 | //output: Complete: some_url 24 | .subscribe(result => console.log(result)); 25 | 26 | const customizableRetry = retryTimes => obs => obs.retry(retryTimes).catch(_ => Rx.Observable.of('ERROR!')); 27 | 28 | //faking request 29 | const secondSubscribe = Rx.Observable 30 | .of('some_url') 31 | .mergeMap(url => examplePromise(url)) 32 | // could reuse error handling logic in multiple places with let 33 | .let(customizableRetry(3)) 34 | //output: Complete: some_url 35 | .subscribe(result => console.log(result)); 36 | ``` 37 | 38 | ##### Example 2: Applying map with let 39 | 40 | ( [jsBin](http://jsbin.com/jiyupaxomo/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/6n7w3b22/) ) 41 | 42 | ```js 43 | //emit array as a sequence 44 | const source = Rx.Observable.from([1,2,3,4,5]); 45 | //demonstrating the difference between let and other operators 46 | const test = source 47 | .map(val => val + 1) 48 | /* 49 | this would fail, let behaves differently than most operators 50 | val in this case is an observable 51 | */ 52 | //.let(val => val + 2) 53 | .subscribe(val => console.log('VALUE FROM ARRAY: ', val)); 54 | 55 | const subscribe = source 56 | .map(val => val + 1) 57 | //'let' me have the entire observable 58 | .let(obs => obs.map(val => val + 2)) 59 | //output: 4,5,6,7,8 60 | .subscribe(val => console.log('VALUE FROM ARRAY WITH let: ', val)); 61 | ``` 62 | 63 | ##### Example 3: Applying multiple operators with let 64 | 65 | ( [jsBin](http://jsbin.com/zamizapaho/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/gxsq1woc/) ) 66 | 67 | ```js 68 | //emit array as a sequence 69 | const source = Rx.Observable.from([1,2,3,4,5]); 70 | 71 | //let provides flexibility to add multiple operators to source observable then return 72 | const subscribeTwo = source 73 | .map(val => val + 1) 74 | .let(obs => obs 75 | .map(val => val + 2) 76 | //also, just return evens 77 | .filter(val => val % 2 === 0) 78 | ) 79 | //output: 4,6,8 80 | .subscribe(val => console.log('let WITH MULTIPLE OPERATORS: ', val)); 81 | ``` 82 | 83 | ##### Example 4: Applying operators through function 84 | 85 | ( [jsBin](http://jsbin.com/vojelelamu/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/ah09dL9e/) ) 86 | 87 | ```js 88 | //emit array as a sequence 89 | const source = Rx.Observable.from([1,2,3,4,5]); 90 | 91 | //pass in your own function to add operators to observable 92 | const obsArrayPlusYourOperators = (yourAppliedOperators) => { 93 | return source 94 | .map(val => val + 1) 95 | .let(yourAppliedOperators) 96 | }; 97 | const addTenThenTwenty = obs => obs.map(val => val + 10).map(val => val + 20); 98 | const subscribe = obsArrayPlusYourOperators(addTenThenTwenty) 99 | //output: 32, 33, 34, 35, 36 100 | .subscribe(val => console.log('let FROM FUNCTION:', val)); 101 | ``` 102 | 103 | 104 | ### Additional Resources 105 | * [let](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/let.md) :newspaper: - Official docs 106 | 107 | --- 108 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/let.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/let.ts) 109 | -------------------------------------------------------------------------------- /operators/utility/topromise.md: -------------------------------------------------------------------------------- 1 | # toPromise 2 | #### 연산자(operator) 정의: `toPromise() : Promise` 3 | 4 | ## Convert observable to promise. 5 | 6 | ### Examples 7 | 8 | ##### Example 1: Basic Promise 9 | 10 | ( [jsBin](http://jsbin.com/favoqecixi/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/thykc9up/) ) 11 | 12 | ```js 13 | //return basic observable 14 | const sample = val => Rx.Observable.of(val).delay(5000); 15 | //convert basic observable to promise 16 | const example = sample('First Example') 17 | .toPromise() 18 | //output: 'First Example' 19 | .then(result => { 20 | console.log('From Promise:', result); 21 | }); 22 | ``` 23 | 24 | ##### Example 2: Using Promise.all 25 | 26 | ( [jsBin](http://jsbin.com/hutiyicaco/1/edit?js,console) | [jsFiddle](https://jsfiddle.net/btroncone/xzu6u7hs/) ) 27 | 28 | ```js 29 | //return basic observable 30 | const sample = val => Rx.Observable.of(val).delay(5000); 31 | /* 32 | convert each to promise and use Promise.all 33 | to wait for all to resolve 34 | */ 35 | const example = () => { 36 | return Promise.all([ 37 | sample('Promise 1').toPromise(), 38 | sample('Promise 2').toPromise() 39 | ]); 40 | } 41 | //output: ["Promise 1", "Promise 2"] 42 | example().then(val => { 43 | console.log('Promise.all Result:', val); 44 | }); 45 | ``` 46 | 47 | 48 | ### Additional Resources 49 | * [toPromise](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/topromise.md) :newspaper: - Official Docs 50 | 51 | --- 52 | > :file_folder: Source Code: [https://github.com/ReactiveX/rxjs/blob/master/src/operator/toPromise.ts](https://github.com/ReactiveX/rxjs/blob/master/src/operator/toPromise.ts) 53 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learn-rxjs", 3 | "version": "0.0.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "asap": { 8 | "version": "2.0.6", 9 | "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", 10 | "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", 11 | "dev": true 12 | }, 13 | "classnames": { 14 | "version": "2.2.5", 15 | "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz", 16 | "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0=", 17 | "dev": true 18 | }, 19 | "core-js": { 20 | "version": "1.2.7", 21 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", 22 | "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=", 23 | "dev": true 24 | }, 25 | "encoding": { 26 | "version": "0.1.12", 27 | "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", 28 | "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", 29 | "dev": true, 30 | "requires": { 31 | "iconv-lite": "0.4.19" 32 | } 33 | }, 34 | "fbjs": { 35 | "version": "0.8.16", 36 | "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz", 37 | "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=", 38 | "dev": true, 39 | "requires": { 40 | "core-js": "1.2.7", 41 | "isomorphic-fetch": "2.2.1", 42 | "loose-envify": "1.3.1", 43 | "object-assign": "4.1.1", 44 | "promise": "7.3.1", 45 | "setimmediate": "1.0.5", 46 | "ua-parser-js": "0.7.14" 47 | } 48 | }, 49 | "gitbook-markdown-css": { 50 | "version": "1.1.0", 51 | "resolved": "https://registry.npmjs.org/gitbook-markdown-css/-/gitbook-markdown-css-1.1.0.tgz", 52 | "integrity": "sha1-i7DHp3W7zXXZ11D34SlQtwl1HcQ=", 53 | "dev": true 54 | }, 55 | "gitbook-styleguide": { 56 | "version": "7.9.3", 57 | "resolved": "https://registry.npmjs.org/gitbook-styleguide/-/gitbook-styleguide-7.9.3.tgz", 58 | "integrity": "sha1-b5QoBUjXMEc/oj7Y+mh3keLYC+k=", 59 | "dev": true, 60 | "requires": { 61 | "classnames": "2.2.5", 62 | "gitbook-markdown-css": "1.1.0", 63 | "moment": "2.18.1", 64 | "moment-duration-format": "1.3.0", 65 | "octicons": "3.4.1", 66 | "react-sticky": "5.0.8", 67 | "roboto-fontface": "0.6.1" 68 | } 69 | }, 70 | "iconv-lite": { 71 | "version": "0.4.19", 72 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", 73 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", 74 | "dev": true 75 | }, 76 | "is-stream": { 77 | "version": "1.1.0", 78 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 79 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 80 | "dev": true 81 | }, 82 | "isomorphic-fetch": { 83 | "version": "2.2.1", 84 | "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", 85 | "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=", 86 | "dev": true, 87 | "requires": { 88 | "node-fetch": "1.7.3", 89 | "whatwg-fetch": "2.0.3" 90 | } 91 | }, 92 | "js-tokens": { 93 | "version": "3.0.2", 94 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 95 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 96 | "dev": true 97 | }, 98 | "loose-envify": { 99 | "version": "1.3.1", 100 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 101 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 102 | "dev": true, 103 | "requires": { 104 | "js-tokens": "3.0.2" 105 | } 106 | }, 107 | "moment": { 108 | "version": "2.18.1", 109 | "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", 110 | "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=", 111 | "dev": true 112 | }, 113 | "moment-duration-format": { 114 | "version": "1.3.0", 115 | "resolved": "https://registry.npmjs.org/moment-duration-format/-/moment-duration-format-1.3.0.tgz", 116 | "integrity": "sha1-VBdxtfh6BJzGVUBHXTrZZnN9aQg=", 117 | "dev": true 118 | }, 119 | "node-fetch": { 120 | "version": "1.7.3", 121 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", 122 | "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", 123 | "dev": true, 124 | "requires": { 125 | "encoding": "0.1.12", 126 | "is-stream": "1.1.0" 127 | } 128 | }, 129 | "object-assign": { 130 | "version": "4.1.1", 131 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 132 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", 133 | "dev": true 134 | }, 135 | "octicons": { 136 | "version": "3.4.1", 137 | "resolved": "https://registry.npmjs.org/octicons/-/octicons-3.4.1.tgz", 138 | "integrity": "sha1-BCw+QzoBdiEto/LmGkhn57lVV7E=", 139 | "dev": true 140 | }, 141 | "promise": { 142 | "version": "7.3.1", 143 | "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", 144 | "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", 145 | "dev": true, 146 | "requires": { 147 | "asap": "2.0.6" 148 | } 149 | }, 150 | "prop-types": { 151 | "version": "15.6.0", 152 | "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", 153 | "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=", 154 | "dev": true, 155 | "requires": { 156 | "fbjs": "0.8.16", 157 | "loose-envify": "1.3.1", 158 | "object-assign": "4.1.1" 159 | } 160 | }, 161 | "react-sticky": { 162 | "version": "5.0.8", 163 | "resolved": "https://registry.npmjs.org/react-sticky/-/react-sticky-5.0.8.tgz", 164 | "integrity": "sha1-1fhflpd/QQCB15KrgYhsYixdixQ=", 165 | "dev": true, 166 | "requires": { 167 | "prop-types": "15.6.0" 168 | } 169 | }, 170 | "roboto-fontface": { 171 | "version": "0.6.1", 172 | "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.6.1.tgz", 173 | "integrity": "sha1-vVarPtTkovKaG9IPv1+S6eTPNUA=", 174 | "dev": true 175 | }, 176 | "setimmediate": { 177 | "version": "1.0.5", 178 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 179 | "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", 180 | "dev": true 181 | }, 182 | "ua-parser-js": { 183 | "version": "0.7.14", 184 | "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz", 185 | "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o=", 186 | "dev": true 187 | }, 188 | "whatwg-fetch": { 189 | "version": "2.0.3", 190 | "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz", 191 | "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ=", 192 | "dev": true 193 | } 194 | } 195 | } 196 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "learn-rxjs", 3 | "version": "0.0.1", 4 | "description": "Learn RxJS 5 Gitbook", 5 | "main": "", 6 | "dependencies": {}, 7 | "devDependencies": { 8 | "gitbook-styleguide": "^7.9.3", 9 | "jasmine": "^2.4.1", 10 | "lodash.isequal": "^4.2.0", 11 | "rxjs": "^5.0.0-beta.2" 12 | }, 13 | "scripts": { 14 | "gb": "gitbook build" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/tienne/learn-rxjs.git" 19 | }, 20 | "keywords": [ 21 | "rxjs" 22 | ], 23 | "author": "David Kwon ", 24 | "contributors": [ 25 | { 26 | "name": "Huy Le" 27 | } 28 | ], 29 | "license": "MIT", 30 | "bugs": { 31 | "url": "https://github.com/tienne/lean-rxjs.git/issues" 32 | }, 33 | "homepage": "https://github.com/tienne/lean-rxjs.git#readme" 34 | } 35 | -------------------------------------------------------------------------------- /recipes/README.md: -------------------------------------------------------------------------------- 1 | # Recipes 2 | 3 | RxJS를 배우는 데 도움이 되는 일반적인 예시와 흥미로운 자료들입니다. 4 | 5 | ### Contents 6 | * [Smart Counter](smartcounter.md) 7 | 8 | -------------------------------------------------------------------------------- /recipes/smartcounter.md: -------------------------------------------------------------------------------- 1 | # Smart Counter 2 | 3 | An interesting element on interfaces which involve dynamically updating numbers is a smart counter, or odometer effect. Instead of jumping a number up and down, quickly counting to the desired number can achieve a cool effect. An example of a popular library that accomplishes this is [odometer](https://github.com/HubSpot/odometer) by [Hubspot](https://github.com/HubSpot). Let's see how we can accomplish something similar with just a few lines of RxJS. 4 | 5 | 6 | 7 | #### Vanilla JS 8 | 9 | ( [JSBin](http://jsbin.com/jojucaqiki/1/edit?js,output) | [JSFiddle](https://jsfiddle.net/btroncone/au4sqvxu/) ) 10 | ```js 11 | // utility functions 12 | const takeUntilFunc = (endRange, currentNumber) => { 13 | return endRange > currentNumber 14 | ? val => val <= endRange 15 | : val => val >= endRange; 16 | }; 17 | 18 | const positiveOrNegative = (endRange, currentNumber) => { 19 | return endRange > currentNumber ? 1 : -1; 20 | }; 21 | 22 | const updateHTML = id => val => document.getElementById(id).innerHTML = val; 23 | // display 24 | const input = document.getElementById('range'); 25 | const updateButton = document.getElementById('update'); 26 | 27 | const subscription = (function(currentNumber) { 28 | return Rx.Observable 29 | .fromEvent(updateButton, 'click') 30 | .map(_ => parseInt(input.value)) 31 | .switchMap(endRange => { 32 | return Rx.Observable.timer(0, 20) 33 | .mapTo(positiveOrNegative(endRange, currentNumber)) 34 | .startWith(currentNumber) 35 | .scan((acc, curr) => acc + curr) 36 | // .delayWhen(//easing here) 37 | .takeWhile(takeUntilFunc(endRange, currentNumber)) 38 | }) 39 | .do(v => currentNumber = v) 40 | .startWith(currentNumber) 41 | .subscribe(updateHTML('display')); 42 | }(0)); 43 | 44 | ``` 45 | 46 | ###### HTML 47 | ```html 48 | 49 | 50 |

0

51 | ``` 52 | 53 | We can easily take our vanilla smart counter and wrap it in any popular component based UI library. Below is an example of an Angular smart counter component which takes an `Input` of the updated end ranges and performs the appropriate transition. 54 | 55 | #### Angular Version 56 | 57 | ```js 58 | @Component({ 59 | selector: 'number-tracker', 60 | template: ` 61 |

{{ currentNumber }}

62 | ` 63 | }) 64 | export class NumberTrackerComponent implements OnDestroy { 65 | @Input() 66 | set end(endRange: number) { 67 | this._counterSub$.next(endRange); 68 | } 69 | public currentNumber = 0; 70 | private _counterSub$ = new Subject(); 71 | private _subscription : Subscription; 72 | 73 | constructor() { 74 | this._subscription = this._counterSub$ 75 | .switchMap(endRange => { 76 | return timer(0, 20) 77 | .mapTo(this.positiveOrNegative(endRange, this.currentNumber)) 78 | .startWith(this.currentNumber) 79 | .scan((acc, curr) => acc + curr) 80 | // .delayWhen(i => { 81 | // easing here 82 | // }) 83 | .takeWhile(this.takeUntilFunc(endRange, this.currentNumber)); 84 | }) 85 | .subscribe(val => this.currentNumber = val); 86 | } 87 | 88 | private positiveOrNegative(endRange, currentNumber) { 89 | return endRange > currentNumber ? 1 : -1; 90 | } 91 | 92 | private takeUntilFunc(endRange, currentNumber) { 93 | return endRange > currentNumber 94 | ? val => val <= endRange 95 | : val => val >= endRange; 96 | } 97 | 98 | ngOnDestroy() { 99 | this._subscription.unsubscribe(); 100 | } 101 | } 102 | ``` 103 | 104 | ### Operators Used 105 | * [fromEvent](../operators/creation/fromevent.md) 106 | * [map](../operators/transformation/map.md) 107 | * [mapTo](../operators/transformation/mapto.md) 108 | * [scan](../operators/transformation/scan.md) 109 | * [startWith](../operators/combination/startwith.md) 110 | * [switchMap](../operators/transformation/switchmap.md) 111 | * [takeWhile](../operators/filtering/takewhile.md) 112 | -------------------------------------------------------------------------------- /wallaby.js: -------------------------------------------------------------------------------- 1 | module.exports = wallaby => ({ 2 | files: [ 3 | {pattern: 'operators/specs/helpers/*.ts', instrument: false} 4 | ], 5 | 6 | tests: ['operators/specs/**/*-spec.ts'], 7 | compilers: { 8 | '**/*.ts': wallaby.compilers.typeScript({ 9 | module: 1, // commonjs 10 | target: 1, // ES5 11 | }) 12 | }, 13 | env: { 14 | type: 'node' 15 | }, 16 | testFramework: 'jasmine', 17 | setup: function (wallaby) { 18 | require('./operators/specs/helpers/test-helper'); 19 | } 20 | }); --------------------------------------------------------------------------------