SlideShare a Scribd company logo
1 of 73
Download to read offline
Async Redux Actions With RxJS
… a love story. <3
Ben Lesh
RxJS 5 Lead
Senior Engineer
Netflix UI Platform Team
Twitter: @benlesh
GitHub: blesh
What is redux?
• Red UX – making your whole site red
• A shelter specializing in abandoned pet ducks
• SF startup for bio-engineered foie gras
• An evil recycling program for unwanted ducks
What is redux?
• A library for managing state with reducers
• Basic functional programming wizardry
brought to the masses
• A brilliant piece of work by Dan Abramov (and
many others)
What’s a reducer?
A simple function that takes state
and an action, and returns a new
state
What’s a reducer?
• Sometimes it returns the same state
(state, action) => state
• Sometimes it returns a new state
(state, action) => state + action.value
Reducers in Redux
const reducer = (state = { value: 0 }, action) => {
switch (action.type) {
case ‘INCREMENT’:
return { value: state.value + 1 };
case ‘DECREMENT’:
return { value: state.value – 1 };
default:
return state;
}
};
Reducers are great for managing state!
An action notifies you of a change,
you return a new state! So easy!
Redux reducers handle state
transitions, but they must be
handled synchronously
But what about async?
• User interactions (mouse, keyboard, etc)
• AJAX
• Web Sockets
• Animations
• Workers, et al
A LOT of async results
can be handled synchronously
• Click a button and update a value
• Select an option and update a value
• Get a single AJAX request and update view
• Mouse moves updating some coordinates
Well, some async
is harder than others…
• AJAX cancellation
• Composed AJAX
• Debounced form submissions
• Drag and drop
• Advanced web socket use
What do these “harder” async
stories have in common?
Composing multiple async sources.
…and cancellation!.
In redux, we use middleware to
manage async
Most redux middlewares use
callbacks or promises
Callbacks
The most primitive way to handle asynchrony in
JavaScript is with callbacks
getSomeData((data) => {
dispatch({ type: ‘I_HAVE_DATA’, data });
});
Callback Hell
(aka “the flying V”)
getSomeData(id, (data) => {
dispatch({ type: ‘SOME_DATA’, data });
getSomeData(data.parentId, (parent) => {
dispatch({ type: ‘MORE_DATA’, data });
getSomeData(parent.parentId, (grandparent) => {
dispatch({ type: ‘DATAX3_YOLO_LOL’, data });
});
});
});
Promises provide a cleaner solution
getSomeData(id)
.then(data => {
dispatch({ type: ‘SOME_DATA’, data });
return getSomeData(data.parentId);
})
.then(data => {
dispatch({ type: ‘MORE_DATA’, data });
return getSomeData(data.parentId);
})
.then(data => {
dispatch({ type: ‘DATAX3_YOLO_LOL’, data });
})
Promises
• Guaranteed Future
• Immutable
• Single Value
• Caching
These two features can be problematic
in modern web applications
Promises can’t be cancelled
This means you’re executing code
you don’t want to
Why cancellation is important
• Auto-complete
• Changing views/routes before data finishes
loading
• Tearing down resources
Loading view data without cancellation
Daredevil
Loading view data without cancellation
Daredevil
The Get Down
Since you can’t cancel the previous promise,
you’re stuck processing the response
and somehow signaling “disinterest”
Loading view data without cancellation
Here’s Daredevil!
Daredevil
A better scenario
Daredevil
The Get Down
Ideally, when we make a new request
we can abort the the old one
so it’s never handled and processed
A better scenario
Thanks, Kent C Dodds!
But these days “resources” are
cheap, right?
Netflix targets devices that are 465x
slower than your laptop
Times are changing
• Laptops and desktops are very fast
• Tablets
• Smartphones
• Industrial devices
• SmartTVs
• Appliances
• Wearables
Promises are a single value
Which of these are single value?
• User interactions (mouse, keyboard, etc)
• AJAX
• Web Sockets
• Animations
• Workers, et al
What do we use?
Observables
• A set of events
• Any number of values
• Over any amount of time
• Cancellable
• Lazy
RxJS
Observables and functions to create
and compose Observables
RxJS
“Lodash for async”
RxJS provides many ways to create
Observables
• interval(1000)
• fromEvent(button, ‘click’)
• from([1, 2, 3, 4]);
• of(‘hello’);
• ajax.getJSON(‘http://example.com’);
• webSocket(‘ws://echo.websocket.com’);
• many, many more…
Subscribing to an observable
myObservable.subscribe(x => console.log(x));
Subscribing to an observable
myObservable.subscribe(
x => console.log(x),
err => console.error(err)
);
Subscribing to an observable
myObservable.subscribe(
x => console.log(x),
err => console.error(err) ,
() => console.info(‘complete’)
);
Subscribing to an observable
const subscription = myObservable.subscribe(
x => console.log(x),
err => console.error(err) ,
() => console.info(‘complete’)
);
subscription.unsubscribe();
We have sets of events that we
can cancel!
Okay, now what?
Sets can be transformed
map, filter, reduce
Sets can be combined
concat, merge, zip
Observables are sets with
another dimension: TIME
buffer, throttle, debounce,
combineLatest
Observables are lazy so they can
be resubscribed
retry, repeat
There is an error path, so we can
catch, just like promise
myObservable.catch(err => Observable.of(‘handled’))
You can do just about anything
with RxJS and Observables!
- redux documentation
Well…
Redux has amazing tooling,
community and support around it.
Redux with middleware
provides solid architecture patterns
Async in redux without middleware
Reducer
instance state
handler kicking off async
render
Component
Async in redux with middleware
(and react-redux)
Reducer
Epic
Stateless Component
Let’s combine RxJS and redux!
redux-observable
Epic middleware for redux
What’s an “Epic”?
A function that takes a stream of all actions
dispatched, and returns a stream of actions to
dispatch.
const pingPongEpic = (action$, store) =>
action$.ofType(‘PING’)
.map(action => ({ type: ‘PONG’ });
What’s an “Epic”?
“Actions in, actions out”
const pingPongEpic = (action$, store) =>
action$.ofType(‘PING’)
.map(action => ({ type: ‘PONG’ });
Basic middleware setup
import { createStore, applyMiddlware } from ‘redux’;
import { createEpicMiddleware } from ‘redux-observable’;
import reducerFn, { epicFn } from ‘./redux/updown’;
const epicMiddleware = createEpicMiddleware(epicFn);
const store = createStore(
reducerFn,
applyMiddleware(epicMiddleware)
);
Idiomatic redux increment decrement
with added debounce
const upEpic = (action$, store) =>
action$.ofType(‘UP’)
.debounceTime(1000)
.map(() => ({ type: ‘INCREMENT’ }));
const downEpic = (action$, store) =>
action$.ofType(‘DOWN’)
.debounceTime(1000)
.map(() => ({ type: ‘DECREMENT’ }));
export const updownEpic = combineEpics(upEpic, downEpic);
Idiomatic redux increment decrement
with added debounce
export default const updown = (state = { value: 0 }, action) =>
{
switch (action.type) {
case ‘INCREMENT’:
return { value: state.value + 1 };
case ‘DECREMENT’:
return { value: state.value – 1 };
default:
return state;
}
};
Idiomatic redux increment decrement
with added debounce
WARNING: Don’t read all of this…
Auto-Complete Plain JS
Auto-Complete Epic
export const autoCompleteEpic = (action$, store) =>
action$.ofType(‘LOAD_QUERY’)
.debounceTime(500)
.switchMap(action =>
ajax.getJSON(`http://endpoint/q=${action.value}`)
.map(results => ({ type: ‘QUERY_RESULTS’, results }))
);
compose in cancellation via dispatched
actions
export const autoCompleteEpic = (action$, store) =>
action$.ofType(‘LOAD_QUERY’)
.debounceTime(500)
.switchMap(action =>
ajax.getJSON(`http://endpoint/q=${action.value}`)
.map(results => ({ type: ‘QUERY_RESULTS’, results }))
.takeUntil(action$.ofType(‘CANCEL_QUERY’))
);
Multiplexed Socket Plain JS
Multiplexed Socket Epic
const socket = new WebSocketSubject('ws://stock/endpoint');
const stockTickerEpic = (action$, store) =>
action$.ofType('GET_TICKER_STREAM')
.mergeMap(action =>
socket.multiplex(
() => ({ sub: action.ticker }),
() => ({ unsub: action.ticker }),
msg => msg.ticker === action.ticker
)
.retryWhen(
err => window.navigator.onLine ?
Observable.timer(1000) :
Observable.fromEvent(window, 'online')
)
.takeUntil(
action$.ofType('CLOSE_TICKER_STREAM')
.filter(closeAction => closeAction.ticker === action.ticker)
)
.map(tick => ({ type: 'TICKER_TICK', tick }))
);
The Good
• Makes it very easy to compose and control
complex async tasks with RxJS and redux
• Can use redux tooling
• You don’t end up managing your own Rx
subscriptions
• If used with react-redux, makes all of your
components stateless
The Bad
• Need to know redux in advance
• Should learn RxJS in advance
• RxJS has a bit of a learning curve
redux-observable
https://github.com/redux-observable/redux-observable
Co-Author Jay Phelps
Twitter: @_jayphelps
Github: jayphelps
Thank you!
@benlesh

More Related Content

What's hot

Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streamsmattpodwysocki
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術名辰 洪
 
History of jQuery
History of jQueryHistory of jQuery
History of jQueryjeresig
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simplerAlexander Mostovenko
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KThomas Fuchs
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptjnewmanux
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the mastersAra Pehlivanian
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was BornDomenic Denicola
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2Jeado Ko
 
Tweaking the interactive grid
Tweaking the interactive gridTweaking the interactive grid
Tweaking the interactive gridRoel Hartman
 
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureFDConf
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jscacois
 

What's hot (20)

Async Frontiers
Async FrontiersAsync Frontiers
Async Frontiers
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
 
RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術RxJS - 封裝程式的藝術
RxJS - 封裝程式的藝術
 
History of jQuery
History of jQueryHistory of jQuery
History of jQuery
 
rx.js make async programming simpler
rx.js make async programming simplerrx.js make async programming simpler
rx.js make async programming simpler
 
Rxjs kyivjs 2015
Rxjs kyivjs 2015Rxjs kyivjs 2015
Rxjs kyivjs 2015
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2KZepto.js, a jQuery-compatible mobile JavaScript framework in 2K
Zepto.js, a jQuery-compatible mobile JavaScript framework in 2K
 
Understanding Asynchronous JavaScript
Understanding Asynchronous JavaScriptUnderstanding Asynchronous JavaScript
Understanding Asynchronous JavaScript
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Expert JavaScript tricks of the masters
Expert JavaScript  tricks of the mastersExpert JavaScript  tricks of the masters
Expert JavaScript tricks of the masters
 
Boom! Promises/A+ Was Born
Boom! Promises/A+ Was BornBoom! Promises/A+ Was Born
Boom! Promises/A+ Was Born
 
Luis Atencio on RxJS
Luis Atencio on RxJSLuis Atencio on RxJS
Luis Atencio on RxJS
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
XQuery Rocks
XQuery RocksXQuery Rocks
XQuery Rocks
 
Tweaking the interactive grid
Tweaking the interactive gridTweaking the interactive grid
Tweaking the interactive grid
 
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 

Similar to Async Redux Actions With RxJS - React Rally 2016

WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...GeeksLab Odessa
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Oscar Renalias
 
RxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptRxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptViliam Elischer
 
Playing With Fire - An Introduction to Node.js
Playing With Fire - An Introduction to Node.jsPlaying With Fire - An Introduction to Node.js
Playing With Fire - An Introduction to Node.jsMike Hagedorn
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSAdam L Barrett
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasminePaulo Ragonha
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)Chris Richardson
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...Ben Teese
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptGuy Royse
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for youSimon Willison
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Domenic Denicola
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailJavascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailCliffano Subagio
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupHenrik Engström
 

Similar to Async Redux Actions With RxJS - React Rally 2016 (20)

WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
WebCamp:Front-end Developers Day. Александр Мостовенко "Rx.js - делаем асинхр...
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 
RxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScriptRxJS - The Reactive extensions for JavaScript
RxJS - The Reactive extensions for JavaScript
 
Playing With Fire - An Introduction to Node.js
Playing With Fire - An Introduction to Node.jsPlaying With Fire - An Introduction to Node.js
Playing With Fire - An Introduction to Node.js
 
Think Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJSThink Async: Asynchronous Patterns in NodeJS
Think Async: Asynchronous Patterns in NodeJS
 
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...apidays LIVE Australia - Building distributed systems on the shoulders of gia...
apidays LIVE Australia - Building distributed systems on the shoulders of gia...
 
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and JasmineSingle Page Web Applications with CoffeeScript, Backbone and Jasmine
Single Page Web Applications with CoffeeScript, Backbone and Jasmine
 
NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)NodeJS: the good parts? A skeptic’s view (jax jax2013)
NodeJS: the good parts? A skeptic’s view (jax jax2013)
 
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
The Return of JavaScript: 3 Open-Source Projects that are driving JavaScript'...
 
Advanced redux
Advanced reduxAdvanced redux
Advanced redux
 
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScriptjQuery & 10,000 Global Functions: Working with Legacy JavaScript
jQuery & 10,000 Global Functions: Working with Legacy JavaScript
 
How to make Ajax work for you
How to make Ajax work for youHow to make Ajax work for you
How to make Ajax work for you
 
Rxjs marble-testing
Rxjs marble-testingRxjs marble-testing
Rxjs marble-testing
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Yavorsky
YavorskyYavorsky
Yavorsky
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
 
Javascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To TailJavascript Everywhere From Nose To Tail
Javascript Everywhere From Nose To Tail
 
Activator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetupActivator and Reactive at Play NYC meetup
Activator and Reactive at Play NYC meetup
 

Recently uploaded

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxAna-Maria Mihalceanu
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Nikki Chapple
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFMichael Gough
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsYoss Cohen
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesManik S Magar
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...BookNet Canada
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfAarwolf Industries LLC
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024TopCSSGallery
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Kaya Weers
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Jeffrey Haguewood
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentPim van der Noll
 

Recently uploaded (20)

A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
A Glance At The Java Performance Toolbox
A Glance At The Java Performance ToolboxA Glance At The Java Performance Toolbox
A Glance At The Java Performance Toolbox
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
Microsoft 365 Copilot: How to boost your productivity with AI – Part one: Ado...
 
All These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDFAll These Sophisticated Attacks, Can We Really Detect Them - PDF
All These Sophisticated Attacks, Can We Really Detect Them - PDF
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
Infrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platformsInfrared simulation and processing on Nvidia platforms
Infrared simulation and processing on Nvidia platforms
 
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotesMuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
MuleSoft Online Meetup Group - B2B Crash Course: Release SparkNotes
 
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
Transcript: New from BookNet Canada for 2024: BNC SalesData and LibraryData -...
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Landscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdfLandscape Catalogue 2024 Australia-1.pdf
Landscape Catalogue 2024 Australia-1.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024Top 10 Hubspot Development Companies in 2024
Top 10 Hubspot Development Companies in 2024
 
Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)Design pattern talk by Kaya Weers - 2024 (v2)
Design pattern talk by Kaya Weers - 2024 (v2)
 
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
Email Marketing Automation for Bonterra Impact Management (fka Social Solutio...
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native developmentEmixa Mendix Meetup 11 April 2024 about Mendix Native development
Emixa Mendix Meetup 11 April 2024 about Mendix Native development
 

Async Redux Actions With RxJS - React Rally 2016

  • 1.
  • 2. Async Redux Actions With RxJS … a love story. <3
  • 3. Ben Lesh RxJS 5 Lead Senior Engineer Netflix UI Platform Team Twitter: @benlesh GitHub: blesh
  • 4. What is redux? • Red UX – making your whole site red • A shelter specializing in abandoned pet ducks • SF startup for bio-engineered foie gras • An evil recycling program for unwanted ducks
  • 5.
  • 6. What is redux? • A library for managing state with reducers • Basic functional programming wizardry brought to the masses • A brilliant piece of work by Dan Abramov (and many others)
  • 7. What’s a reducer? A simple function that takes state and an action, and returns a new state
  • 8. What’s a reducer? • Sometimes it returns the same state (state, action) => state • Sometimes it returns a new state (state, action) => state + action.value
  • 9. Reducers in Redux const reducer = (state = { value: 0 }, action) => { switch (action.type) { case ‘INCREMENT’: return { value: state.value + 1 }; case ‘DECREMENT’: return { value: state.value – 1 }; default: return state; } };
  • 10. Reducers are great for managing state! An action notifies you of a change, you return a new state! So easy!
  • 11. Redux reducers handle state transitions, but they must be handled synchronously
  • 12. But what about async? • User interactions (mouse, keyboard, etc) • AJAX • Web Sockets • Animations • Workers, et al
  • 13. A LOT of async results can be handled synchronously • Click a button and update a value • Select an option and update a value • Get a single AJAX request and update view • Mouse moves updating some coordinates
  • 14. Well, some async is harder than others… • AJAX cancellation • Composed AJAX • Debounced form submissions • Drag and drop • Advanced web socket use
  • 15. What do these “harder” async stories have in common? Composing multiple async sources. …and cancellation!.
  • 16. In redux, we use middleware to manage async
  • 17. Most redux middlewares use callbacks or promises
  • 18. Callbacks The most primitive way to handle asynchrony in JavaScript is with callbacks getSomeData((data) => { dispatch({ type: ‘I_HAVE_DATA’, data }); });
  • 19. Callback Hell (aka “the flying V”) getSomeData(id, (data) => { dispatch({ type: ‘SOME_DATA’, data }); getSomeData(data.parentId, (parent) => { dispatch({ type: ‘MORE_DATA’, data }); getSomeData(parent.parentId, (grandparent) => { dispatch({ type: ‘DATAX3_YOLO_LOL’, data }); }); }); });
  • 20. Promises provide a cleaner solution getSomeData(id) .then(data => { dispatch({ type: ‘SOME_DATA’, data }); return getSomeData(data.parentId); }) .then(data => { dispatch({ type: ‘MORE_DATA’, data }); return getSomeData(data.parentId); }) .then(data => { dispatch({ type: ‘DATAX3_YOLO_LOL’, data }); })
  • 21. Promises • Guaranteed Future • Immutable • Single Value • Caching These two features can be problematic in modern web applications
  • 22. Promises can’t be cancelled This means you’re executing code you don’t want to
  • 23. Why cancellation is important • Auto-complete • Changing views/routes before data finishes loading • Tearing down resources
  • 24. Loading view data without cancellation
  • 25. Daredevil Loading view data without cancellation
  • 26. Daredevil The Get Down Since you can’t cancel the previous promise, you’re stuck processing the response and somehow signaling “disinterest” Loading view data without cancellation Here’s Daredevil!
  • 28. Daredevil The Get Down Ideally, when we make a new request we can abort the the old one so it’s never handled and processed A better scenario
  • 29. Thanks, Kent C Dodds!
  • 30. But these days “resources” are cheap, right? Netflix targets devices that are 465x slower than your laptop
  • 31. Times are changing • Laptops and desktops are very fast • Tablets • Smartphones • Industrial devices • SmartTVs • Appliances • Wearables
  • 32. Promises are a single value
  • 33. Which of these are single value? • User interactions (mouse, keyboard, etc) • AJAX • Web Sockets • Animations • Workers, et al
  • 34. What do we use?
  • 35. Observables • A set of events • Any number of values • Over any amount of time • Cancellable • Lazy
  • 36. RxJS Observables and functions to create and compose Observables
  • 38. RxJS provides many ways to create Observables • interval(1000) • fromEvent(button, ‘click’) • from([1, 2, 3, 4]); • of(‘hello’); • ajax.getJSON(‘http://example.com’); • webSocket(‘ws://echo.websocket.com’); • many, many more…
  • 39. Subscribing to an observable myObservable.subscribe(x => console.log(x));
  • 40. Subscribing to an observable myObservable.subscribe( x => console.log(x), err => console.error(err) );
  • 41. Subscribing to an observable myObservable.subscribe( x => console.log(x), err => console.error(err) , () => console.info(‘complete’) );
  • 42. Subscribing to an observable const subscription = myObservable.subscribe( x => console.log(x), err => console.error(err) , () => console.info(‘complete’) ); subscription.unsubscribe();
  • 43. We have sets of events that we can cancel! Okay, now what?
  • 44. Sets can be transformed map, filter, reduce
  • 45. Sets can be combined concat, merge, zip
  • 46. Observables are sets with another dimension: TIME buffer, throttle, debounce, combineLatest
  • 47. Observables are lazy so they can be resubscribed retry, repeat
  • 48. There is an error path, so we can catch, just like promise myObservable.catch(err => Observable.of(‘handled’))
  • 49. You can do just about anything with RxJS and Observables!
  • 51. Well… Redux has amazing tooling, community and support around it.
  • 52. Redux with middleware provides solid architecture patterns
  • 53. Async in redux without middleware Reducer instance state handler kicking off async render Component
  • 54. Async in redux with middleware (and react-redux) Reducer Epic Stateless Component
  • 55. Let’s combine RxJS and redux!
  • 57. What’s an “Epic”? A function that takes a stream of all actions dispatched, and returns a stream of actions to dispatch. const pingPongEpic = (action$, store) => action$.ofType(‘PING’) .map(action => ({ type: ‘PONG’ });
  • 58. What’s an “Epic”? “Actions in, actions out” const pingPongEpic = (action$, store) => action$.ofType(‘PING’) .map(action => ({ type: ‘PONG’ });
  • 59. Basic middleware setup import { createStore, applyMiddlware } from ‘redux’; import { createEpicMiddleware } from ‘redux-observable’; import reducerFn, { epicFn } from ‘./redux/updown’; const epicMiddleware = createEpicMiddleware(epicFn); const store = createStore( reducerFn, applyMiddleware(epicMiddleware) );
  • 60. Idiomatic redux increment decrement with added debounce const upEpic = (action$, store) => action$.ofType(‘UP’) .debounceTime(1000) .map(() => ({ type: ‘INCREMENT’ })); const downEpic = (action$, store) => action$.ofType(‘DOWN’) .debounceTime(1000) .map(() => ({ type: ‘DECREMENT’ })); export const updownEpic = combineEpics(upEpic, downEpic);
  • 61. Idiomatic redux increment decrement with added debounce export default const updown = (state = { value: 0 }, action) => { switch (action.type) { case ‘INCREMENT’: return { value: state.value + 1 }; case ‘DECREMENT’: return { value: state.value – 1 }; default: return state; } };
  • 62. Idiomatic redux increment decrement with added debounce
  • 63. WARNING: Don’t read all of this…
  • 65. Auto-Complete Epic export const autoCompleteEpic = (action$, store) => action$.ofType(‘LOAD_QUERY’) .debounceTime(500) .switchMap(action => ajax.getJSON(`http://endpoint/q=${action.value}`) .map(results => ({ type: ‘QUERY_RESULTS’, results })) );
  • 66. compose in cancellation via dispatched actions export const autoCompleteEpic = (action$, store) => action$.ofType(‘LOAD_QUERY’) .debounceTime(500) .switchMap(action => ajax.getJSON(`http://endpoint/q=${action.value}`) .map(results => ({ type: ‘QUERY_RESULTS’, results })) .takeUntil(action$.ofType(‘CANCEL_QUERY’)) );
  • 68. Multiplexed Socket Epic const socket = new WebSocketSubject('ws://stock/endpoint'); const stockTickerEpic = (action$, store) => action$.ofType('GET_TICKER_STREAM') .mergeMap(action => socket.multiplex( () => ({ sub: action.ticker }), () => ({ unsub: action.ticker }), msg => msg.ticker === action.ticker ) .retryWhen( err => window.navigator.onLine ? Observable.timer(1000) : Observable.fromEvent(window, 'online') ) .takeUntil( action$.ofType('CLOSE_TICKER_STREAM') .filter(closeAction => closeAction.ticker === action.ticker) ) .map(tick => ({ type: 'TICKER_TICK', tick })) );
  • 69. The Good • Makes it very easy to compose and control complex async tasks with RxJS and redux • Can use redux tooling • You don’t end up managing your own Rx subscriptions • If used with react-redux, makes all of your components stateless
  • 70. The Bad • Need to know redux in advance • Should learn RxJS in advance • RxJS has a bit of a learning curve
  • 72. Co-Author Jay Phelps Twitter: @_jayphelps Github: jayphelps

Editor's Notes

  1. Remove mutation?
  2. Have a redux tie-in (dispatch instead of doStuff) note threading of errors
  3. Note promises are only 1 event, this is 0-N.