SlideShare a Scribd company logo
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
You will learn RxJS in 2017
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
You will learn RxJS in 2017
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)


You will learn RxJS in 2017
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
•
• ( )
• RxJS
• 30 RxJS
• Observable Spec Proposal
• Learn RxJS
•
•
• AutoComplete
•
•

More Related Content

Similar to You will learn RxJS in 2017 (20)

PDF
RxJS - 封裝程式的藝術
名辰 洪
 
PDF
RxJS Evolved
trxcllnt
 
PDF
Reactive programming with RxJS - ByteConf 2018
Tracy Lee
 
PPTX
Functional Reactive Programming with RxJS
stefanmayer13
 
PDF
Functional Reactive Programming in JavaScript
zupzup.org
 
PDF
Rxjs kyivjs 2015
Alexander Mostovenko
 
PDF
DZone_RC_RxJS
Luis Atencio
 
PPTX
Reactive programming with rx java
CongTrung Vnit
 
PPTX
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
PDF
Functional Web Development
FITC
 
PPTX
Angular2 rxjs
Christoffer Noring
 
PPTX
Reactive programming every day
Vadym Khondar
 
PPTX
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Codemotion
 
PDF
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
GeeksLab Odessa
 
PDF
rx.js make async programming simpler
Alexander Mostovenko
 
PPTX
Rxjs swetugg
Christoffer Noring
 
PPTX
Luis Atencio on RxJS
Luis Atencio
 
PDF
Mattia Manzati - Real-World MobX Project Architecture - Codemotion Rome 2019
Codemotion
 
PDF
RxJS - The Reactive extensions for JavaScript
Viliam Elischer
 
PDF
Cycle.js - A functional reactive UI framework
Nikos Kalogridis
 
RxJS - 封裝程式的藝術
名辰 洪
 
RxJS Evolved
trxcllnt
 
Reactive programming with RxJS - ByteConf 2018
Tracy Lee
 
Functional Reactive Programming with RxJS
stefanmayer13
 
Functional Reactive Programming in JavaScript
zupzup.org
 
Rxjs kyivjs 2015
Alexander Mostovenko
 
DZone_RC_RxJS
Luis Atencio
 
Reactive programming with rx java
CongTrung Vnit
 
Functional Reactive Programming (FRP): Working with RxJS
Oswald Campesato
 
Functional Web Development
FITC
 
Angular2 rxjs
Christoffer Noring
 
Reactive programming every day
Vadym Khondar
 
Samuele Resca - REACTIVE PROGRAMMING, DAMN. IT IS NOT ABOUT REACTJS - Codemot...
Codemotion
 
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
GeeksLab Odessa
 
rx.js make async programming simpler
Alexander Mostovenko
 
Rxjs swetugg
Christoffer Noring
 
Luis Atencio on RxJS
Luis Atencio
 
Mattia Manzati - Real-World MobX Project Architecture - Codemotion Rome 2019
Codemotion
 
RxJS - The Reactive extensions for JavaScript
Viliam Elischer
 
Cycle.js - A functional reactive UI framework
Nikos Kalogridis
 

Recently uploaded (20)

PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
PPTX
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
PPTX
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
PDF
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
PDF
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
PDF
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
PDF
Staying Human in a Machine- Accelerated World
Catalin Jora
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
PDF
July Patch Tuesday
Ivanti
 
PDF
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
PPTX
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
PPTX
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
PDF
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
PDF
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
Go Concurrency Real-World Patterns, Pitfalls, and Playground Battles.pdf
Emily Achieng
 
COMPARISON OF RASTER ANALYSIS TOOLS OF QGIS AND ARCGIS
Sharanya Sarkar
 
Webinar: Introduction to LF Energy EVerest
DanBrown980551
 
"Beyond English: Navigating the Challenges of Building a Ukrainian-language R...
Fwdays
 
Using FME to Develop Self-Service CAD Applications for a Major UK Police Force
Safe Software
 
IoT-Powered Industrial Transformation – Smart Manufacturing to Connected Heal...
Rejig Digital
 
Staying Human in a Machine- Accelerated World
Catalin Jora
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
What Makes Contify’s News API Stand Out: Key Features at a Glance
Contify
 
July Patch Tuesday
Ivanti
 
Jak MŚP w Europie Środkowo-Wschodniej odnajdują się w świecie AI
dominikamizerska1
 
The Project Compass - GDG on Campus MSIT
dscmsitkol
 
Future Tech Innovations 2025 – A TechLists Insight
TechLists
 
“NPU IP Hardware Shaped Through Software and Use-case Analysis,” a Presentati...
Edge AI and Vision Alliance
 
How Startups Are Growing Faster with App Developers in Australia.pdf
India App Developer
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
From Sci-Fi to Reality: Exploring AI Evolution
Svetlana Meissner
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Ad

You will learn RxJS in 2017

  • 1. You Will Learn RxJS In 2017 Jerry Hong
  • 3. ...
  • 4. • RxJS ? Lodash ? • RxJS ?
  • 5. var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })
  • 6. 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; }) } })
  • 7. var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } }) ...
  • 8. var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } }) Callback
  • 9. var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } }) Promise
  • 10. 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
  • 13. [1, 2, 3].forEach(x => console.log(x)); 1 2 3 ForEach
  • 14. [1, 2, 3].map(x => x + 1); [2, 3, 4] Map
  • 15. [1, 2, 3].filter(x => x % 2 === 1); [1, 3] Filter
  • 16. [[1, 2], [2, 3], [5, 6]].concatAll(); [1, 2, 2, 3, 5, 6] concatAll
  • 18. 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 } ] }] };
  • 19. 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 } ] }] };
  • 20. user.courseLists .map(courseList => courseList.courses .filter(course => course.rating === 5)) .concatAll() .forEach(course => console.log(course)) rating 5
  • 22. ... [{x: 31, y: 23}, {x: 41, y: 23}, {x: 12, y: 45}]
  • 23. {x: 31, y: 23}...{x: 41, y: 23}...{x: 12, y: 45}
  • 25.
  • 28. 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
  • 30. 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
  • 32. document.addEventListener('click', (event) => { ... }) Push var x = iterator.next() Pull
  • 33. Push API • DOM Events • Web sockets • Node Streams • XMLHttpRequest • setInterval • Service Workers
  • 36. var mouseMove = Observable .fromEvent(elem, 'mousemove') Observable for Event
  • 37. API • DOM Events • Web sockets • Node Streams • XMLHttpRequest • setInterval • Service Workers => Observable
  • 38. var handler = (event) => console.log(event) // subscribe document.addEventListener('mousemove', handler) // unsubscribe document.removeEventListener('mousemove', handler)
  • 39. // subscribe var subscription = mouseMove.subscribe(console.log) // unsubscribe subscription.unsubscribe() Observable
  • 40. // subscribe mouseMove.subscribe( event => console.log(event), err => console.log('Error: ' + err), () => console.log('complete') ) // unsubscribe mouseMove.unsubscribe() Observable
  • 43. '--1----2---3'.map(x => x + 1); 2 3 4 Map
  • 44. '--1----2---3'.filter(x => x % 2 === 1); 1 3 Filter
  • 45. [[1, 2], [2, 3], [5, 6]].concatAll(); [1, 2, 2, 3, 5, 6] concatAll
  • 46. '--o-------o'.concatAll();
 
 -1--2| -1-2-3| 1 2 1 2 3 concatAll '---1--2---1-2-3'
  • 48. const dragDOM = document.getElementById('drag'); const mouseDown = Observable .fromEvent(dragDOM, 'mousedown'); const mouseUp = Observable .fromEvent(document, 'mouseup'); const mouseMove = Observable .fromEvent(document, 'mousemove');
  • 49. 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
  • 50. var isRequesting = false; window.addEventListener('scroll', function() { if(someOffsetBottom < 0 && !isRequesting) { isRequesting = true; fetch('url...') .then(res => { // do something change view isRequesting = false; }) } })
  • 51. var scroll = Observable.fromEvent(window, 'scroll'); scroll .filter(event => someOffsetBottom < 0) .map(event => fetch('url...')) .exhaust() .subscribe(res => { // do something change view })
  • 53. • 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, )
  • 54. Promise AJAX • DOM Event (0 - N values) • AJAX (1 value) • WebSocket (0 - N values) • Server Sent Event (0 - N values) • Animation (0 - N values, )
  • 55. Observable • DOM Event (0 - N values) • AJAX (1 value) • WebSocket (0 - N values) • Server Sent Event (0 - N values) • Animation (0 - N values, )
  • 56. RxJS • Promise • Observable ES7 • RxJS 5 • RxJS 5 Observable Spec Proposal • framework (library) RxJS • Angular 2 • Vue-rx • Redux-Observable
  • 57. RxJS
  • 58. RxJS • ( ) • ( ) • • •
  • 59. RxJS • Hello World app • • ( )
  • 60. • RxJS • 30 RxJS • Observable Spec Proposal • Learn RxJS