웹 프론트엔드 개발자의 얕고...

92
웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기 김훈민, NAVER 스마트에디터 3.0 http://huns.me

Transcript of 웹 프론트엔드 개발자의 얕고...

Page 1: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

웹�프론트엔드�개발자의��얕고�넓은�Rx�이야기김훈민,�NAVER�스마트에디터�3.0�

http://huns.me

Page 2: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

비동기와�이벤트�기반�프로그램을�작성하는�데�필요한�Observable�시퀀스�처리�라이브러리

Rx

Page 3: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

2005 현재

2007,��Volta

2009,��RX.NET

2010,��RXJS

2012,��오픈소스�공개

2013�RxJava

Page 4: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

“Of�all�the�work�I’ve�done�in�my�career�so�far,�this�is�the�most�exciting.�[…]�I�know�it’s�a�bold�statement,�

but�I�really�believe�that�the�problem�of�asynchronous�programming�events�has�been�

solved.”��

https://campustechnology.com/articles/2009/08/10/microsofts-new-.net-rx-framework-tackles-challenges-of-asynchronous-programming.aspx�

Page 5: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

목차

1.�Rx를�지탱하는�세�가지�키워드�2.�요즘�들어�왜�자주�보일까?�

3.�함수형�리액티브�프로그래밍�

4.�웹�프론트엔드,�그리고�RxJS

Page 6: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

#1�

Rx를�지탱하는�세�가지�키워드Reactive�Programming�

LINQ�to�Events�

Scheduler

Page 7: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Reactive�Programming데이터�플로우와�상태�변경을�전파한다는��

생각에�근간을�둔�프로그래밍�패러다임�

Reactive�Programming�in�Wikipedia,�The�Free�Encyclopedia

Page 8: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Reactive�systems�[…]�are�repeatedly�prompted��by�the�outside�world�and�their�role�is�to�

continusouly�respond��external�inputs�

-�On�the�development�of�reactive�systems,�1985�-�

http://dl.acm.org/citation.cfm?id=101990

Page 9: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

자극은�밖에서�안으로�흐름�자극이�있어야만�반응하는�수동성

반응

Page 10: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 11: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Iterator Datanext()

Page 12: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Observer Datasubscribe()

Page 13: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

어떤�체계�간에�존재하는�다음과�같은�논리적�성질.�각각�1:1로�대응하는�개념�xi와�yi(i=1,�2,�…)로�이루어진�체계�S1={x1,�x2,�…},�S2={y1,�y2,�…}�등이�있다고�하자.�여기서�S1과�S2는�전체로서는�같은�체계라도�괜찮다.�S1에�관하여�명제�r(x1,�x2,�…,�xn)가�성립될�때�이�명제에�있어서�각�xi를�대응하는�yi로�치환한�

명제�P(y1,�y2,�…,�yn)가�S2에�관하여�성립된다.�S1,�S2�간에�존재하는�이와�같은�논리적�성질을�쌍대성이라�하고�xi,�yi를�쌍대인�개념�r(x1,�x2,�…),�P(y1,�y2,�…)를�쌍대�명제라�한다.�전기�회로에서는�표와�같이�대응할�때마다�쌍대성이�존재하여�중요하다.�

[네이버�지식백과]�쌍대성�[duality]�(IT용어사전,�한국정보통신기술협회)�

Page 14: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 15: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

A와�B의�본질이�같다�(약간의�정신�승리)

어떤�체계�간에�존재하는�다음과�같은�

논리적�성질.�각각�1:1로�대응하는�개

념�xi와�yi(i=1,�2,�…)로�이루어진�체계�

S1={x1,�x2,�…},�S2={y1,�y2,�…}�등

이�있다고�하자.�여기서�S1과�S2는�전

체로서는�같은�체계라도�괜찮다.�S1에�

관하여�명제�r(x1,�x2,�…,�xn)가�성립될�

때�이�명제에�있어서�각�xi를�대응하는�

yi로�치환한�명제�P(y1,�y2,�…,�yn)가�S2

에�관하여�성립된다.�S1,�S2�간에�존재

하는�이와�같은�논리적�성질을�쌍대성

이라�하고�xi,�yi를�쌍대인�개념�r(x1,�

x2,�…),�P(y1,�y2,�…)를�쌍대�명제라�한

다.�전기�회로에서는�표와�같이�대응할�

때마다�쌍대성이�존재하여�중요하다.

Page 16: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

eventIterable�(pull)

Observable�(push)

데이터�가져오기 T�next() next(T)

에러�처리 throws�Exception error(Exception)

완료 !hasNext() complete()

Page 17: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

LINQ�to�Events이벤트와�LINQ의�개념을�결합한��

오퍼레이터(Operator)�제공

Page 18: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Language��INtergrated��Query에릭�마이어가�만든�통합�질의�언어�

C#�3.0부터�등장�

데이터�질의�문법�설탕

Page 19: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

//Query syntax: IEnumerable<int> numQuery1 = from num in numbers where num % 2 == 0 orderby num select num; //Method syntax: IEnumerable<int> numQuery2 = numbers .Where(num => num % 2 == 0) .OrderBy(n => n);

Page 20: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

//Query syntax: IEnumerable<int> numQuery1 = from num in numbers where num % 2 == 0 orderby num select num; //Method syntax: IEnumerable<int> numQuery2 = numbers .Where(num => num % 2 == 0) .OrderBy(n => n);

Page 21: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Your�Mouse�is��a�DataBase=�Observable�+�LINQ

Page 22: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 23: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Mouse�Move�Event

Page 24: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const targetElement = document.getElementById('dragElement'); const drag$ = Rx.Observable .fromEvent(targetElement, 'mouseup'); drag$ .flatMap(ev => ({ startX: ev.pageX, startY: ev.pageY })); drag$.subscribe(pos => { console.log(pos); });

Page 25: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Mouse�Move�Event

Page 26: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const targetElement = document.getElementById('dragElement'); const drag$ = Rx.Observable .fromEvent(targetElement, 'mouseup'); drag$ .flatMap(ev => ({ startX: ev.pageX, startY: ev.pageY })); drag$.subscribe(pos => { console.log(pos); });

Page 27: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Subscribe

Page 28: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const targetElement = document.getElementById('dragElement'); const drag$ = Rx.Observable .fromEvent(targetElement, 'mouseup'); drag$ .flatMap(ev => ({ startX: ev.pageX, startY: ev.pageY })); drag$.subscribe(pos => { console.log(pos); });

Page 29: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Scheduler비동기(멀티스레드)�환경에서��

오퍼레이터�실행�시점�제어

Page 30: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 31: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

#2�

요즘�들어,�왜�자주�보일까?Rx만�잘난�것도�아닌데�

왜�굳이�Rx?�

Page 32: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 33: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 34: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

https://medium.com/reactive-programming/what-is-reactive-programming-bc9fa7f4a7fc#.ddo2ci9wx

Page 35: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Reactive�Manifesto�http://www.reactivemanifesto.org/

Responsive

Page 36: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Reactive�Manifesto�http://www.reactivemanifesto.org/

Responsive

Elastic Resilient

Page 37: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Reactive�Manifesto�http://www.reactivemanifesto.org/

Responsive

Resilient

Message-Driven

Elastic

Page 38: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

callback�promise�generator�async/await�…

Page 39: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

(Compositionality)

구성성

Page 40: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

춘향은�잠에서�퍼뜩�깼다

Page 41: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

춘향�/�은�/�잠�/�에서�/�퍼뜩�/�깼다

Page 42: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

춘향�/�은�/�자-/�ㅁ�/�에서�/�퍼뜩�/�깨-�/�었-�/�다

Page 43: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 44: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 45: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 46: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 47: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

1

2

3

Page 48: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

http://labs.bench.co/blog/2014/12/10/microservices-at-bench-intro

Page 49: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

https://www.kirupa.com/react/components.htm

Page 50: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Functional�+�Rx

복잡�->�분리�->�결합

동시성 구성성

Page 51: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 52: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

sum�=�a�+�b

Page 53: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

sum�=�a�+�b

a와�b의�합을�sum에�할당?

Page 54: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

sum�=�a�+�b

정체성,�관계�정의

Page 55: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

a

b

sum

Page 56: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const a = document.getElementById('a'); const a$ = Rx.Observable .fromEvent(a, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(a.value, 10));

const b = document.getElementById('b'); const b$ = Rx.Observable .fromEvent(b, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(b.value, 10)); const result$ = Rx.Observable .combineLatest(a$, b$) .map(values => values.reduce((acc, cur) => acc + cur)); result$.subscribe(res => document.getElementById('result').value = res);

a

Page 57: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const a = document.getElementById('a'); const a$ = Rx.Observable .fromEvent(a, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(a.value, 10));

const b = document.getElementById('b'); const b$ = Rx.Observable .fromEvent(b, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(b.value, 10));const result$ = Rx.Observable .combineLatest(a$, b$) .map(values => values.reduce((acc, cur) => acc + cur)); result$.subscribe(res => document.getElementById('result').value = res);

a

b

Page 58: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const a = document.getElementById('a'); const a$ = Rx.Observable .fromEvent(a, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(a.value, 10));

const b = document.getElementById('b'); const b$ = Rx.Observable .fromEvent(b, 'keyup') .map(e => parseInt(e.target.value || 0, 10)) .startWith(parseInt(b.value, 10));

const sum$ = Rx.Observable .combineLatest(a$, b$) .map(values => values.reduce((acc, cur) => acc + cur)); sum$.subscribe(res => document.getElementById('result').value = res);

a

b

sum

Page 59: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

#3�

함수형��리액티브��프로그래밍(FRP)함수형�리액티브�프로그래밍(FRP)을��

둘러싼�혼란과�진실

Page 60: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

It�is�sometimes�called�“functional�reactive�

programming”�but�this�is�a�misnomer.�

ReactiveX�may�be�functional,�and�it�may�be�

reactive,�but�“functional�reactive�programming”�is�a�different�animal.�

http://reactivex.io/intro.html�

Page 61: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 62: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Functional��Reactive��AnimatioNby�Conal�Elliott�and�Paul�Hudak,�1997�

인터랙티브�3D�그래픽�처리�

표현과�모델링의�분리�

시간에�따라�변하는�값을�표현(Behavior)�

함수형�리액티브�프로그래밍(FRP)의�시작

Page 63: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

http://images.slideplayer.com/26/8448601/slides/slide_4.jpg

Page 64: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 65: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

wiggle�=�sin(pi�*�time)

Page 66: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

wiggle�=�sin(pi�*�time)

Behavior

Page 67: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

moveXY(x,�y,�image)

Page 68: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

moveXY�wiggle�0�image

Page 69: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

charlotte�=�importBitmap�"../Media/charlotte.bmp"�moveXY�wiggle�0�charlotte

http://conal.net/fran/tutorial.htm

Page 70: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

leftRightCharlotte�=�moveXY�wiggle�0�charlotte�upDownPat�=�moveXY�0�waggle�pat�

charlottePatDance�=�leftRightCharlotte�`over`�upDownPat

Page 71: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

https://prezi.com/rfgd0rzyiqp_/controlling-time-and-space/

Page 72: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

"Original�FRP"�refers�to�denotational�and�continuous-time�functional�programming�using�behaviors�and�events.

https://github.com/conal/talk-2015-essence-and-origins-of-frp�https://medium.com/@andrestaltz/why-i-cannot-say-frp-but-i-just-did-d5ffaa23973b#.xtc4pmnco

Page 73: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

const result$ = Rx.Observable .combineLatest(a$, b$) .map(values => { values.reduce((acc, cur) => acc + cur) });

Page 74: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

불연속�값(descret�value)�처리!�스트림�결합시�사이드�이펙트�발생!�

구성성(compositionality)�결여!

Page 75: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

ones 1 2

hundreds 200

sum 101 202

시간

100

Page 76: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

ones 1 2

hundreds 200

sum 101 202

시간

100

Page 77: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

ones 1 2

hundreds 200

sum 101 202

시간

102

순간�불일치(glitch)

100

Page 78: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기
Page 79: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Rx�=�반응성�-�시간Rx는�동시성을�매개변수화하여�

쌍대성을�이용하여�현실적인�대안을�제시

http://csl.stanford.edu/~christos/pldi2010.fit/meijer.duality.pdf

Page 80: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

eventIterable�(pull)

Observable�(push)

데이터�가져오기 T�next() next(T)

에러�처리 throws�Exception error(Exception)

완료 !hasNext() complete()

None�BlockingBlocking

Page 81: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

#4�

웹�프론트엔드,�그리고�RxJS웹�프론트엔드에서�RxJS는�어떤�의미가�있을까?

Page 82: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

도메인�모델,�OOP�설계�KVO(Key-Value�Observing)

Page 83: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

양방향�데이터�바인딩�풍부한�디렉티브

Page 84: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

가상�DOM을�이용한�렌더링�순수�함수와�같은�컴포넌트

Page 85: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

순수�함수�조합�단방향�데이터�플로우�신뢰할�수�있는�단일�출처�불변�상태

Page 86: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

MVI(Model-View-Intent)�순환�스트림�설계�함수형�프로그래밍

Page 87: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

+�Reactive�+�Functional

OOP FP

Page 88: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

Angular2…?

OOP FP

2

Page 89: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

But,��with�RxJS�or�Redux

OOP FP

2

Page 90: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

주변을�둘러�보시라Elm에서�영감을�얻은�redux,�cycle.js�

다른�진영�또는�클래식한�기술에서�새로운�통찰�획득�

Rx는�좋은�자극제

Page 91: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

정리비동기�해법으로�탄생�

Observable�+�LINQ�+�Scheduler�

RP�and�Functional,�But�Not�FRP�

복잡도�증가�->�분리�->�결합�

핵심은�구성성(Compositionality)�

새로운�패러다임이�주는�자극

Page 92: 웹 프론트엔드 개발자의 얕고 넓은 Rx 이야기

감사합니다