You will learn RxJS in 2017

61
You Will Learn RxJS In 2017 Jerry Hong

Transcript of You will learn RxJS in 2017

You Will Learn RxJS In 2017

Jerry Hong

RxJS

...

• RxJS ? Lodash ?

• RxJS ?

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

...

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

Callback

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

Promise

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

Complex State

Functional Programming

[1, 2, 3].forEach(x => console.log(x)); 1 2 3

ForEach

[1, 2, 3].map(x => x + 1); [2, 3, 4]

Map

[1, 2, 3].filter(x => x % 2 === 1); [1, 3]

Filter

[[1, 2], [2, 3], [5, 6]].concatAll(); [1, 2, 2, 3, 5, 6]

concatAll

var user = { id: 888, name: 'JerryHong', courseLists: [{ name: 'My Courses', courses: [ { title: 'React ', rating: 5 }, { title: ' ', rating: 4 } ] }, { name: 'New Release', courses: [ { title: 'Vue 2 ', rating: 5 }, { title: 'RxJS ', rating: 5 } ] }] };

var user = { id: 888, name: 'JerryHong', courseLists: [{ name: 'My Courses', courses: [ { title: 'React ', rating: 5 }, { title: ' ', rating: 4 } ] }, { name: 'New Release', courses: [ { title: 'Vue 2 ', rating: 5 }, { title: 'RxJS ', rating: 5 } ] }] };

var user = { id: 888, name: 'JerryHong', courseLists: [{ name: 'My Courses', courses: [ { title: 'React ', rating: 5 }, { title: ' ', rating: 4 } ] }, { name: 'New Release', courses: [ { title: 'Vue 2 ', rating: 5 }, { title: 'RxJS ', rating: 5 } ] }] };

var user = { id: 888, name: 'JerryHong', courseLists: [{ name: 'My Courses', courses: [ { title: 'React ', rating: 5 }, { title: ' ', rating: 4 } ] }, { name: 'New Release', courses: [ { title: 'Vue 2 ', rating: 5 }, { title: 'RxJS ', rating: 5 } ] }] };

user.courseLists .map(courseList => courseList.courses .filter(course => course.rating === 5)) .concatAll() .forEach(course => console.log(course))

rating 5

elmt.mouseDowns .map(mouseEvent => document.mouseMoves .filter takeUntil(document.mouseUps)) .concatAll() .forEach(pos => image.position = pos);

...

[{x: 31, y: 23}, {x: 41, y: 23}, {x: 12, y: 45}]

{x: 31, y: 23}...{x: 41, y: 23}...{x: 12, y: 45}

(Collection)

Iterator

Observer

var iterator = [1, 2, 3][Symbol.iterator](); iterator.next(); { value: 1, done: false } iterator.next(); { value: 2, done: false } iterator.next(); { value: 3, done: false } iterator.next(); { value: undefined, done: true }

Iterator

iterator Map, Filter, ConcatAll

document.addEventListener( 'mousemove', function next(event){ console.log(event) }) { clientX: 55, clientY: 121 } { clientX: 12, clientY: 124 } { clientX: 23, clientY: 234 } { clientX: 234, clientY: 12 } { clientX: 123, clientY: 45 } { clientX: 56, clientY: 133 }

Observer

Iterator Observer

document.addEventListener('click', (event) => { ... })

Push

var x = iterator.next()

Pull

Push API• DOM Events

• Web sockets

• Node Streams

• XMLHttpRequest

• setInterval

• Service Workers

Observable

Observable

var mouseMove = Observable .fromEvent(elem, 'mousemove')

Observable for Event

API• DOM Events

• Web sockets

• Node Streams

• XMLHttpRequest

• setInterval

• Service Workers

=> Observable

var handler = (event) => console.log(event)

// subscribe document.addEventListener('mousemove', handler)

// unsubscribe document.removeEventListener('mousemove', handler)

// subscribe var subscription = mouseMove.subscribe(console.log)

// unsubscribe subscription.unsubscribe()

Observable

// subscribe mouseMove.subscribe( event => console.log(event), err => console.log('Error: ' + err), () => console.log('complete') )

// unsubscribe mouseMove.unsubscribe()

Observable

-------1---2----3----|

Marble Diagram

time

-------1---2----3----

'--1----2---3'.forEach(x => console.log(x)); 1 2 3

ForEach

'--1----2---3'.map(x => x + 1); 2 3 4

Map

'--1----2---3'.filter(x => x % 2 === 1); 1 3

Filter

[[1, 2], [2, 3], [5, 6]].concatAll(); [1, 2, 2, 3, 5, 6]

concatAll

'--o-------o'.concatAll(); \ \ -1--2| -1-2-3| 1 2 1 2 3

concatAll

'---1--2---1-2-3'

'--1---2----3'.takeUntil( '--------e'); 1 2 'complete'

takeUntil

'--1---2-|'

const dragDOM = document.getElementById('drag');

const mouseDown = Observable .fromEvent(dragDOM, 'mousedown');

const mouseUp = Observable .fromEvent(document, 'mouseup');

const mouseMove = Observable .fromEvent(document, 'mousemove');

mouseDown .map(event => mouseMove) mouseDown .map(event => mouseMove.takeUntil(mouseUp))mouseDown .map(event => mouseMove mouseDown .map(event => mouseMove.takeUntil(mouseUp)) .concatAll()

mouseDown .map(event => mouseMove.takeUntil(mouseUp)) .concatAll() .subscribe(event => { dragDOM.style.left = event.clientX + 'px'; dragDOM.style.top = event.clientY + 'px'; })

https://jsbin.com/sanefic/1/edit?js,output

var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })

var scroll = Observable.fromEvent(window, 'scroll');

scroll .filter(event => someOffsetBottom < 0) .map(event => fetch('url...')) .exhaust() .subscribe(res => { // do something change view })

RxJS• Promise

• DOM Event

• AJAX

• WebSocket

• Server Sent Event

• Animation

• DOM Event (0 - N values)

• AJAX (1 value)

• WebSocket (0 - N values)

• Server Sent Event (0 - N values)

• Animation (0 - N values, )

Promise AJAX• DOM Event (0 - N values)

• AJAX (1 value)

• WebSocket (0 - N values)

• Server Sent Event (0 - N values)

• Animation (0 - N values, )

Observable • DOM Event (0 - N values)

• AJAX (1 value)

• WebSocket (0 - N values)

• Server Sent Event (0 - N values)

• Animation (0 - N values, )

RxJS• Promise

• Observable ES7

• RxJS 5

• RxJS 5 Observable Spec Proposal

• framework (library) RxJS • Angular 2 • Vue-rx • Redux-Observable

RxJS

RxJS

• ( )

• ( )

RxJS

• Hello World app

• ( )