{"id":20646590,"url":"https://github.com/tienne/study-rxjs","last_synced_at":"2026-03-07T20:03:48.097Z","repository":{"id":98494724,"uuid":"101136400","full_name":"tienne/study-rxjs","owner":"tienne","description":"study rxjs","archived":false,"fork":false,"pushed_at":"2017-08-26T11:33:18.000Z","size":273,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-17T09:45:18.477Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tienne.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-23T04:06:46.000Z","updated_at":"2017-10-27T12:28:57.000Z","dependencies_parsed_at":"2023-06-28T08:30:33.032Z","dependency_job_id":null,"html_url":"https://github.com/tienne/study-rxjs","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tienne%2Fstudy-rxjs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tienne%2Fstudy-rxjs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tienne%2Fstudy-rxjs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tienne%2Fstudy-rxjs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tienne","download_url":"https://codeload.github.com/tienne/study-rxjs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242721881,"owners_count":20174805,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T16:26:26.733Z","updated_at":"2026-03-07T20:03:43.054Z","avatar_url":"https://github.com/tienne.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# 함수형 프로그래밍? 리액티브 프로그래밍?\n\n요즘 함수형 프로그래밍 혹은 리액티브 프로그래밍 같은 용어가 자주 보인다. \n\n이 문서에서는 Reactive 혹은 함수형 프로그래밍에 대한 설명을 깊게 하진 않는다.\n\n왜냐면 설명하자니 너무 어렵다. 그치만 중요하다 개인발전을 좋아하는 개발자라면 꼭 한번 찾아서 읽어보자  \n\nReactiveX 또는 리액티브 프로그래밍 대한 정보는 [나프콘 2016 김훈민님의 발표내용](https://www.youtube.com/watch?v=3FKlYO4okts) 또는 [김훈민님 블로그](http://huns.me/development/2051)에서 자세히 확인이 가능하니 여기서는 ReactiveX에 대해서만 간략하게 알아보자\n\n### ReactiveX란 무엇인가?\n\n공식홈페이지에는 아래와 같이 설명되어있다.\n\u003eReactiveX is a library for composing asynchronous and event-based programs by using observable sequences.\n\n이 내용을 해석하면\n\u003eReactiveX는 observable 시퀀스를 사용하여 비동기 및 이벤트 기반 프로그램을 작성하기위한 라이브러리입니다.\n\n처음 ReactivX는 .NET용 라이브러리로 출시되었으며, 그이후 RxJS / RxJava / Rx++ 등 추가로 출시하면서 오픈소스화 하였다고한다\n\n# RxJs?\n\nReactiveX 시리즈의 JavaScript 구현체 라이브러리가 RxJs\n\n지원 브라우저 현황은 아래와 같다.\n\u003eIE6+, Chrome 4+, FireFox 1+, Node.js v0.4+\n\nAngular 2(이하 Angular)에서 비동기 처리등에 적극 도입했으며, Angular의 필수 라이브러리 중 하나이다. \n\nReactiveX는 비동기의 문제를 해결하기 위해 만들어졌는데, promise / await / generator 등과 무엇이 다르며, 도대체 어떠한 방향으로 해결하고자 했을지 알아보자\n\n# Your mouse is a database\n\n위에 문장은 Rx의 창시자인 Erik Meijer가 한 얘기로 Rx에서 비동기 처리를 위해 `시간`이라는 개념을 도입했다.\n\n아래의 그림을 보면 마우스로 발생되는 이벤트들을 시간이라는 개념으로 표시해두었다.\n![Image](https://github.com/tienne/lean-rxjs/blob/master/images/your_mouse_is_database.jpg?raw=true)\n[그림출저 Erik Meijer의 Twitter]\n\n우리가 일반적으로 알고있는 데이터베이스는 메모리 혹은 디스크 공간에 저장되는 데이터 집합이다.\n근데 마우스가 데이터베이스라면 데이터에 해당하는 것은 무엇일까? 바로 이벤트다. Rx는 이 이벤트조차 데이터로 취급하는거다.\n그 이벤트를 시간이라는 배열(컬렉션)에 담아, 아래와 같은 형태로 관리를 한다.\n\nMouse[click, click, move, move, move]\n\n이것을 `스트림(Stream)`라고 표현한다.\n\nRx에는 이러한 개념에 LINQ(Language Intergrated Query)를 도입했다.[LINQ도 에릭 마이어가 만들었다.] LINQ는 통합 질의 언어로 코드에서 데이터를 가져올때 SQL문처럼 표현할 수 있도록 도와주는 일종의 언어 확장이다.\n\n제공하는 방식으로는 SQL 방식과 메서드 방식이 있다. Rx에서는 메서드 방식을 도입했다.\n\n간단한 예시로 아래를 보자\n\n먼저 SQL 방식이다.\n```csharp\nvar productName = from product in products\n           where product.id == 1\n           select product.name;\n```\n\n그 다음은 메서드 방식이다.\n```csharp\nvar productName = products\n    .Where(product =\u003e product.id == 1)\n    .Select(product =\u003e product.name);\n```\n\n그럼 Rx에서는 LINQ를 어떻게 활용하고 있는지 보자.\n\n```javascript 1.7\nvar button = document.getElementById('submitBtn');\nvar clickStream = Rx.Observable.fromEvent(button, 'click');\n\nclickStream\n  .filter(e =\u003e {\n    return e.altKey;\n  })\n  .subscribe(e =\u003e {\n    console.log(e.clientY);\n  });\n```\n\n쿼리로 표현하면 이런식 아닐까 싶다.\n```SQL\nSELECT clientY FROM clicks where altKey == true;\n```\n\n# RxJs의 구성요소 및 키워드\n\n- Observable: 미래의 값(value)나 이벤트의 호출 가능한 수집의 개념을 나타냄.\n- Observer: Observable에 의해 전달 된 값을 처리하는 콜백 콜렉션.\n- Subscription: Observable의 실행을 나타냄. 주로 실행 취소에 유용함.\n- Operators: map, filter, concat, flatMap 등과 같은 method를 사용하여 컬렉션을 다루는 함수 프로그래밍 스타일을 가능하게하는 순수(pure) 함수.\n- Subject: EventEmitter와 동일하며 여러 Observers에 값 또는 이벤트를 멀티 캐스팅함.\n- Schedulers: 동시 처리를 제어하는 중앙 집중식 디스패처로서 계산이 언제 발생하는지 조정할 수 있다. setTimeout or requestAnimationFrame or others.\n\n각각의 요소들에 대해 알아보자\n\n### Observable\n\n`Observable`은 관찰할 수 있는 대상 혹은 데이터를 지칭합니다. \n\n이 데이터는 ['Rxjs', 'RxJava'] 같은 배열 데이터도 될 수 있고 Ajax 비동기 통신 결과 혹은 클릭 이벤트 등 Observable로 만들 수 있습니다.\n\n간단한 Observable 객체를 만들어보도록 하겠습니다.\n\n```typescript\nconst observable$ = Rx.Observable.create(function(observer) {\n    observer.onNext(1);\n    observer.onNext(2); \n    observer.onNext(3); \n\n    observer.onCompleted();\n});\nobservable$.subscribe(observer);\n```\n객체 observable$은 [1, 2, 3] 같이 표현할 수 있으며, 이러한 `Observable`를 관찰(구독)하는 대상을 `Observer`라고 합니다.\n\nRxJs에선 observable$의 `subscribe` 메서드를 이용해서 `Observer`에 구독할 수 있습니다. \n\n### Observer\n\n`Observer`는 아래처럼 정의되어있습니다.\n\n```typescript\ninterface Observer\u003cT\u003e {\n  closed?: boolean;\n  next: (value: T) =\u003e void;\n  error: (err: any) =\u003e void;\n  complete: () =\u003e void;\n}\n```\n\n- next: 다음 데이터를 불러올때 발생되는 메서드입니다.\n- error: 데이터를 불러오는 과정에서 오류가 발생되었을때 발생되는 메서드입니다.\n- complete: 모든데이터를 다 불러왔을때 발생되는 메서드입니다.\n\n위에서 선언했던 observable$를 구독하여 observer$를 처리 해보도록 하겠습니다.\n```typescript\nconst observable$ = Rx.Observable.create(function(observer) {\n    observer.onNext(1);\n    observer.onNext(2); \n    observer.onNext(3); \n    \n    observer.onCompleted();\n});\n\nconst subscription = observable$.subscribe(\n  (value) =\u003e console.log(`값: ${value}`),\n  (error) =\u003e console.log(`에러: ${error}`),\n  () =\u003e console.log(`완료`)\n);\n\n//구독 취소\n//subscription.unsubscribe();\n\n//결과 console\n//\"값: 1\"\n//\"값: 2\"\n//\"값: 3\"\n//\"완료\"\n```\n\n여기서 변수명 `observable$` 변수 뒤에 $는 해당 변수가 `스트림(stream)` 혹은 `Observable`임을 나타내는 의미입니다.\n\nobservable를 구독하면 리턴값으로 `Subscription`이 생성되는데 위에 구성요소에 설명한거와 같이 `unsubscribe()` 메서드를 이용하여 구독을 취소에 사용됩니다.\n\n### Subscription\n\nobservable$이 `subscribe` 메서드를 호출하여 구독시 Subscription 객체가 생성되며, 이 생성된 subscription의 `unsubscription` 메서드 호출시 구독 취소와 함께 사용되었던 리소스가 제거됩니다.\n`SubScription`은 주로 구독을 취소하여 구독으로 발생된 리소스를 해제하는 할때 사용됩니다. angular에서는 ngOnDestroy에서 `Observable`를 폐기할때 사용합니다.\n\n또한 add 메서드를 이용하여 하위 subscription을 포함시킬 수 있습니다. add로 추가된 하위 subscription은 상위 구독정보가 취소될 경우 같이 구독 취소됩니다.\n\n### Operator\n\n\n ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftienne%2Fstudy-rxjs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftienne%2Fstudy-rxjs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftienne%2Fstudy-rxjs/lists"}