NO MORE PROMISES. LET'S RXJS
REACTIVE EXTENSIONS FOR JAVASCRIPT
A B O U T M E
{
"name": "Ilia Idakiev",
"experience": [
“Google Developer Expert (GDE)“,
"Developer & Co-founder @ HILLGRAND",
"Lecturer in 'Advanced JS' @ Sofia University",
"Contractor / Consultant",
"Public / Private Courses”
],
"involvedIn": [
"Angular Sofia", "SofiaJS / BeerJS",
]
}
!
FUNCTIONAL
PROGRAMMING
REACTIVE EXTENSIONS FOR JAVASCRIPT
FUNCTIONAL PROGRAMMING
▸ Functional programming is a programming paradigm
that treats computation as the evaluation of mathematical
functions and avoids changing-state and mutable data. It is
a declarative programming paradigm, which means
programming is done with expressions or declarations
instead of statements.
REACTIVE EXTENSIONS FOR JAVASCRIPT
IMPERATIVE VS DECLARATIVE PROGRAMMING
function getAdmins(users) {
const admins = [];
for (let i = 0; i < users.length; i++) {
const currentUser = users[i];
if (!currentUser.isAdmin) { continue; }
admins.push(currentUser);
}
return admins;
}
Imperative programming focuses on describing how a
program operates.
function getAdmins(users) {
return users.filter(
currentUser => currentUser.isAdmin
);
}
Declarative programming focuses on expressing the logic
of a computation without describing its control flow.
REACTIVE EXTENSIONS FOR JAVASCRIPT
FUNCTIONAL CONCEPTS
▸ Pure Functions
▸ Composition
▸ Immutability
▸ Higher-order functions (Functions as first-class citizens)
▸ Currying and Partial Application - translating the evaluation of a function that
takes multiple arguments into evaluating a sequence of functions.
▸ Lazy evaluation - evaluate when needed.
REACTIVE EXTENSIONS FOR JAVASCRIPT
REFERENTIAL TRANSPARENCY
▸ An expression is called referentially transparent if it can be replaced with its
corresponding value without changing the program's behaviour. This requires
that the expression is pure, that is to say the expression value must be the same
for the same inputs and its evaluation must have no side effects.
REACTIVE EXTENSIONS FOR JAVASCRIPT
FUNCTIONAL PROGRAMMING ADVANTAGES
▸ Cleaner Code - Easy to test, debug and reason about (no side effects).
▸ Modularity - Breaking large problems into small parts.
▸ Reusability - Pure functions can be reused and composed.
▸ Efficiency - Lazy Evaluation (evaluate when needed)
ASYNCHRONY
REACTIVE EXTENSIONS FOR JAVASCRIPT
ASYNCHRONOUS JAVASCRIPT
▸ Continuation Passing Style (CPS)
▸ CPS with named callbacks (to reduce callback hell)
▸ Futures and Promises / async - await
▸ Async data streams - RxJS
FUTURES AND PROMISES
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ Futures and promises originated in functional programming and related
paradigms (such as logic programming) to decouple a value (a future) from
how it was computed (a promise), allowing the computation to be done
more flexibly, notably by parallelizing it.
WHERE DO PROMISES COME FROM?
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ A Promise is a proxy for a value not necessarily known when the promise is
created.
▸ It allows you to associate handlers with an asynchronous action's eventual
success value or failure reason.
▸ This lets asynchronous methods return values like synchronous methods:
instead of immediately returning the final value, the asynchronous method
returns a promise to supply the value at some point in the future.
PROMISES
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ Pending - initial state, neither fulfilled nor rejected.
▸ Fulfilled - the operation completed successfully.
▸ Rejected - the operation failed.
PROMISE STATES (STATE MACHINE)
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE
const promise = new Promise(function (resolve, reject) {
setTimeout(function () {
const randomNumber = Math.floor(Math.random() * Math.floor(10));
if (randomNumber % 2 === 0) {
resolve('Success');
return;
}
reject('Error');
}, 300);
});
promise.then(console.log).catch(console.error);
Controlling the machine state
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (2)
Promise.resolve(10).then(x => x + 10).then(console.log);
WAIT A MINUTE
THIS LOOKS VERY SIMILAR TO…
REACTIVE EXTENSIONS FOR JAVASCRIPT
JS ARRAYS
[10].map(x => x + 1).forEach(console.log);
WHY IS IT CALLED MAP?
CATEGORY THEORY
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ Mathematical Abstractions - Helps us getting rid of details so we can look at
things a different way.
▸ Main Parts of Category Theory:
▸ Objects and Morphisms (functions) (which form a Category)
▸ Functors
▸ Natural Transformations
CATEGORY THEORY
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORIES
▸ A category consists of a collection of objects (just
abstractions) and morphisms (functions).

(X, Y, Z - objects)
▸ The morphisms must obey the following laws:
▸ They must me composable.
▸ Compositions must me associative.
▸ For each object a, there is an identity morphism.
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORY THEORY IN JAVASCRIPT
add(1, 1) // > 2 - persists type
add(1, 0) // > 1 - identity function
add(1, 2) === add(2, 1) // > 3 - commutative
add(add(1, 2), 3) === add(1, add(2, 3)); // > 6 - associative and composable
multiply(2, add(3, 4)) === add(multiply(2, 3), multiply(2, 4)) // > 14 - distributive
REACTIVE EXTENSIONS FOR JAVASCRIPT
FUNCTORS
▸ A structure-preserving mapping between categories. (the return value is the same
type of functor)
▸ Let A and B be categories. A functor F from A to B is a mapping that:
▸ associates to each object a in A an object F(a) in B.
▸ associates to each morphism f in A a morphism F(f) in B such that the following two
conditions hold:
▸ F(ID(x)) = ID(F(X))
▸ F(g o f) = F(f) o F(g) for all morphisms f: x -> y, g: y -> z in A.
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORY THEORY OBJECTS IN JAVASCRIPT
const containerPrototype = {
map: function (fn) {
return Container(fn(this.value));
}
}
function Container(value) {
return Object.create(containerPrototype, { value: { value } });
}
console.log(Container(10).map(x => x + 100)); // > Container { value: 110 }
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORY THEORY OBJECTS IN JAVASCRIPT
Container(10).map(x => x + 100).map(x => '' + x); // > Container { value: '110' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORY THEORY OBJECTS IN JAVASCRIPT
[10].map(x => x + 100).map(x => '' + x);
REACTIVE EXTENSIONS FOR JAVASCRIPT
CATEGORY THEORY OBJECTS IN JAVASCRIPT
[10].map(x => x + 100).map(x => '' + x);
It’s a functor!
MAYBE FUNCTOR
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // > Maybe { value: null }
console.log(matchFirst('test', /rest/)); // Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // > Maybe { value: null }
console.log(matchFirst('test', /rest/)); // > Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
MAYBE FUNCTOR
const maybePrototype = {
map: function (fn) {
return this.value !== null ? Maybe(fn(this.value)) : Maybe(null);
}
}
function Maybe(value) {
return Object.create(maybePrototype, { value: { value } });
}
function matchFirst(string, regexp) {
return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]);
}
console.log(matchFirst(null, /test/)); // > Maybe { value: null }
console.log(matchFirst('test', /rest/)); // > Maybe { value: null }
console.log(matchFirst('test1test2', /testd/)); // > Maybe { value: 'test1' }
ARE PROMISES FUNCTORS?
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (3)
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (3)
Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
For values which are not promises, .then() acts like an asynchronous .map()
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (4)
Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x);
// > Promise { value: '110' }
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (4)
Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x);
// > Promise { value: '110' }
For values which are promises themselves, .then() acts like
the .flatMap() method from monads.
REACTIVE EXTENSIONS FOR JAVASCRIPT
PROMISE EXAMPLE (4)
Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x);
// > Promise { value: '110' }
It’s flattening the structure! It’s not a functor!
REACTIVE EXTENSIONS FOR JAVASCRIPT
MONADS
▸ An extended functor.
▸ They flatten and map with context
YOU ALREADY ARE USING
MONADS!
REACTIVE EXTENSIONS FOR JAVASCRIPT
ARRAY.PROTOTYPE.FLAT AND ARRAY.PROTOTYPE.FLATMAP
[ 'H', ['e'], ['l'], ['l'], 'o'].flat();
[1, [2], 3].flatMap(val => val * 2)
SO WHAT ABOUT RXJS?
WHAT IS RXJS?
MARBLE TESTING RXJS STREAMS
REACTIVE EXTENSIONS FOR JAVASCRIPT
▸ RxJS is a library for reactive programming using
Observables, to make it easier to compose
asynchronous or callback-based code.
REACTIVE EXTENSIONS FOR JAVASCRIPT
CREATING AN OBSERVABLE (THE OLD WAY)
import 'rxjs/add/observable/of';
import ‘rxjs/add/operator/map';
of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
REACTIVE EXTENSIONS FOR JAVASCRIPT
CREATING AN OBSERVABLE
import { of } from ‘rxjs';
import { map } from ‘rxjs/operators';
of(10).pipe(map(x => x + 100), map(x => '' + x)).subscribe(console.log);
IT’S A FUNCTOR!
REACTIVE EXTENSIONS FOR JAVASCRIPT
CREATING AN OBSERVABLE
import { of } from ‘rxjs';
import { map } from ‘rxjs/operators';
of(of(10), of(10)).pipe(switchMap(x => x), map(x => x + 100)).subscribe(console.log);
IT’S A MONAD!
WHAT ARE THE DIFFERENCES
RXJS AND PROMISES?
REACTIVE EXTENSIONS FOR JAVASCRIPT
CREATING AN OBSERVABLE STREAM (1)
import { from } from ‘rxjs';
import { map } from ‘rxjs/operators';
const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1));
stream$.subscribe(console.log)
// > 2
// > 3
// > 4
// > 5
REACTIVE EXTENSIONS FOR JAVASCRIPT
CREATING AN OBSERVABLE STREAM (2)
import { interval } from ‘rxjs';
import { publish } from ‘rxjs/operators’;
const connectableTimer = interval(1000).pipe(publish());
connectableTimer.connect();
setTimeout(function () {
connectableTimer.subscribe(console.log);
// > 4
// > 5
// > 6
// > 7
// ...
}, 5000)
REACTIVE EXTENSIONS FOR JAVASCRIPT
HOT AND COLD OBSERVABLES
▸ Cold - An observable is “cold” if its underlying producer is created and
activated during subscription.
▸ Hot - An observable is “hot” if its underlying producer is either created or
activated outside of subscription.
1. OBSERVABLES ARE
STREAMS OF DATA(One or more values)
REACTIVE EXTENSIONS FOR JAVASCRIPT
COMMON THINGS THAT WE NEED
▸ debouncing
▸ cancelation
▸ retrying
▸ throttling
▸ timeouts
▸ detect only if something changed
RXJS HAS THEM ALL
2. BETTER FLOW CONTROL
(using the rxjs operators and rxjs observable factories/combiners)
3. DIFFERENT WAYS OF EMITTING DATA
(hot vs cold observables)
4. OBSERVABLES ARE CANCELLABLE
(using unsubscribe)
5. OBSERVABLES ARE LAZY
(we have to explicitly state that we want the observable to start)
6. CONTROLLING TIME(using schedulers)
WHAT IS COMMON ABOUT
RXJS AND PROMISES?
MARBLE TESTING RXJS STREAMS
WHAT IS COMMON ABOUT RXJS AND PROMISES?
▸ They are both monads like.
▸ Both are used to capture the effect of latency.
WHY ARE THEY REACTIVE?
DEMO
MARBLE TESTING RXJS STREAMS
CONNECT
GitHub > https://github.com/iliaidakiev (/slides/ - list of future and past events)
Twitter > @ilia_idakiev
THANK YOU!

No more promises lets RxJS 2 Edit

  • 1.
    NO MORE PROMISES.LET'S RXJS REACTIVE EXTENSIONS FOR JAVASCRIPT
  • 2.
    A B OU T M E { "name": "Ilia Idakiev", "experience": [ “Google Developer Expert (GDE)“, "Developer & Co-founder @ HILLGRAND", "Lecturer in 'Advanced JS' @ Sofia University", "Contractor / Consultant", "Public / Private Courses” ], "involvedIn": [ "Angular Sofia", "SofiaJS / BeerJS", ] } !
  • 3.
  • 4.
    REACTIVE EXTENSIONS FORJAVASCRIPT FUNCTIONAL PROGRAMMING ▸ Functional programming is a programming paradigm that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data. It is a declarative programming paradigm, which means programming is done with expressions or declarations instead of statements.
  • 5.
    REACTIVE EXTENSIONS FORJAVASCRIPT IMPERATIVE VS DECLARATIVE PROGRAMMING function getAdmins(users) { const admins = []; for (let i = 0; i < users.length; i++) { const currentUser = users[i]; if (!currentUser.isAdmin) { continue; } admins.push(currentUser); } return admins; } Imperative programming focuses on describing how a program operates. function getAdmins(users) { return users.filter( currentUser => currentUser.isAdmin ); } Declarative programming focuses on expressing the logic of a computation without describing its control flow.
  • 6.
    REACTIVE EXTENSIONS FORJAVASCRIPT FUNCTIONAL CONCEPTS ▸ Pure Functions ▸ Composition ▸ Immutability ▸ Higher-order functions (Functions as first-class citizens) ▸ Currying and Partial Application - translating the evaluation of a function that takes multiple arguments into evaluating a sequence of functions. ▸ Lazy evaluation - evaluate when needed.
  • 7.
    REACTIVE EXTENSIONS FORJAVASCRIPT REFERENTIAL TRANSPARENCY ▸ An expression is called referentially transparent if it can be replaced with its corresponding value without changing the program's behaviour. This requires that the expression is pure, that is to say the expression value must be the same for the same inputs and its evaluation must have no side effects.
  • 8.
    REACTIVE EXTENSIONS FORJAVASCRIPT FUNCTIONAL PROGRAMMING ADVANTAGES ▸ Cleaner Code - Easy to test, debug and reason about (no side effects). ▸ Modularity - Breaking large problems into small parts. ▸ Reusability - Pure functions can be reused and composed. ▸ Efficiency - Lazy Evaluation (evaluate when needed)
  • 9.
  • 10.
    REACTIVE EXTENSIONS FORJAVASCRIPT ASYNCHRONOUS JAVASCRIPT ▸ Continuation Passing Style (CPS) ▸ CPS with named callbacks (to reduce callback hell) ▸ Futures and Promises / async - await ▸ Async data streams - RxJS
  • 11.
  • 12.
    REACTIVE EXTENSIONS FORJAVASCRIPT ▸ Futures and promises originated in functional programming and related paradigms (such as logic programming) to decouple a value (a future) from how it was computed (a promise), allowing the computation to be done more flexibly, notably by parallelizing it. WHERE DO PROMISES COME FROM?
  • 13.
    REACTIVE EXTENSIONS FORJAVASCRIPT ▸ A Promise is a proxy for a value not necessarily known when the promise is created. ▸ It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. ▸ This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future. PROMISES
  • 14.
    REACTIVE EXTENSIONS FORJAVASCRIPT ▸ Pending - initial state, neither fulfilled nor rejected. ▸ Fulfilled - the operation completed successfully. ▸ Rejected - the operation failed. PROMISE STATES (STATE MACHINE)
  • 15.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE const promise = new Promise(function (resolve, reject) { setTimeout(function () { const randomNumber = Math.floor(Math.random() * Math.floor(10)); if (randomNumber % 2 === 0) { resolve('Success'); return; } reject('Error'); }, 300); }); promise.then(console.log).catch(console.error); Controlling the machine state
  • 16.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (2) Promise.resolve(10).then(x => x + 10).then(console.log);
  • 17.
    WAIT A MINUTE THISLOOKS VERY SIMILAR TO…
  • 18.
    REACTIVE EXTENSIONS FORJAVASCRIPT JS ARRAYS [10].map(x => x + 1).forEach(console.log);
  • 19.
    WHY IS ITCALLED MAP?
  • 20.
  • 21.
    REACTIVE EXTENSIONS FORJAVASCRIPT ▸ Mathematical Abstractions - Helps us getting rid of details so we can look at things a different way. ▸ Main Parts of Category Theory: ▸ Objects and Morphisms (functions) (which form a Category) ▸ Functors ▸ Natural Transformations CATEGORY THEORY
  • 22.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORIES ▸ A category consists of a collection of objects (just abstractions) and morphisms (functions).
 (X, Y, Z - objects) ▸ The morphisms must obey the following laws: ▸ They must me composable. ▸ Compositions must me associative. ▸ For each object a, there is an identity morphism.
  • 23.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORY THEORY IN JAVASCRIPT add(1, 1) // > 2 - persists type add(1, 0) // > 1 - identity function add(1, 2) === add(2, 1) // > 3 - commutative add(add(1, 2), 3) === add(1, add(2, 3)); // > 6 - associative and composable multiply(2, add(3, 4)) === add(multiply(2, 3), multiply(2, 4)) // > 14 - distributive
  • 24.
    REACTIVE EXTENSIONS FORJAVASCRIPT FUNCTORS ▸ A structure-preserving mapping between categories. (the return value is the same type of functor) ▸ Let A and B be categories. A functor F from A to B is a mapping that: ▸ associates to each object a in A an object F(a) in B. ▸ associates to each morphism f in A a morphism F(f) in B such that the following two conditions hold: ▸ F(ID(x)) = ID(F(X)) ▸ F(g o f) = F(f) o F(g) for all morphisms f: x -> y, g: y -> z in A.
  • 25.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORY THEORY OBJECTS IN JAVASCRIPT const containerPrototype = { map: function (fn) { return Container(fn(this.value)); } } function Container(value) { return Object.create(containerPrototype, { value: { value } }); } console.log(Container(10).map(x => x + 100)); // > Container { value: 110 }
  • 26.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORY THEORY OBJECTS IN JAVASCRIPT Container(10).map(x => x + 100).map(x => '' + x); // > Container { value: '110' }
  • 27.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORY THEORY OBJECTS IN JAVASCRIPT [10].map(x => x + 100).map(x => '' + x);
  • 28.
    REACTIVE EXTENSIONS FORJAVASCRIPT CATEGORY THEORY OBJECTS IN JAVASCRIPT [10].map(x => x + 100).map(x => '' + x); It’s a functor!
  • 29.
  • 30.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 31.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 32.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 33.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 34.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 35.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // > Maybe { value: null } console.log(matchFirst('test', /rest/)); // Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 36.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // > Maybe { value: null } console.log(matchFirst('test', /rest/)); // > Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // Maybe { value: 'test1' }
  • 37.
    REACTIVE EXTENSIONS FORJAVASCRIPT MAYBE FUNCTOR const maybePrototype = { map: function (fn) { return this.value !== null ? Maybe(fn(this.value)) : Maybe(null); } } function Maybe(value) { return Object.create(maybePrototype, { value: { value } }); } function matchFirst(string, regexp) { return Maybe(string).map(string => string.match(regexp)).map(matches => matches[0]); } console.log(matchFirst(null, /test/)); // > Maybe { value: null } console.log(matchFirst('test', /rest/)); // > Maybe { value: null } console.log(matchFirst('test1test2', /testd/)); // > Maybe { value: 'test1' }
  • 38.
  • 39.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (3) Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' }
  • 40.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (3) Promise.resolve(10).then(x => x + 100).then(x => '' + x); // > Promise { value: '110' } For values which are not promises, .then() acts like an asynchronous .map()
  • 41.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (4) Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x); // > Promise { value: '110' }
  • 42.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (4) Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x); // > Promise { value: '110' } For values which are promises themselves, .then() acts like the .flatMap() method from monads.
  • 43.
    REACTIVE EXTENSIONS FORJAVASCRIPT PROMISE EXAMPLE (4) Promise.resolve(10).then(x => Promise.resolve(x + 100)).then(x => '' + x); // > Promise { value: '110' } It’s flattening the structure! It’s not a functor!
  • 44.
    REACTIVE EXTENSIONS FORJAVASCRIPT MONADS ▸ An extended functor. ▸ They flatten and map with context
  • 45.
    YOU ALREADY AREUSING MONADS!
  • 46.
    REACTIVE EXTENSIONS FORJAVASCRIPT ARRAY.PROTOTYPE.FLAT AND ARRAY.PROTOTYPE.FLATMAP [ 'H', ['e'], ['l'], ['l'], 'o'].flat(); [1, [2], 3].flatMap(val => val * 2)
  • 47.
  • 48.
  • 49.
    MARBLE TESTING RXJSSTREAMS REACTIVE EXTENSIONS FOR JAVASCRIPT ▸ RxJS is a library for reactive programming using Observables, to make it easier to compose asynchronous or callback-based code.
  • 50.
    REACTIVE EXTENSIONS FORJAVASCRIPT CREATING AN OBSERVABLE (THE OLD WAY) import 'rxjs/add/observable/of'; import ‘rxjs/add/operator/map'; of(10).map(x => x + 100).map(x => '' + x).subscribe(console.log);
  • 51.
    REACTIVE EXTENSIONS FORJAVASCRIPT CREATING AN OBSERVABLE import { of } from ‘rxjs'; import { map } from ‘rxjs/operators'; of(10).pipe(map(x => x + 100), map(x => '' + x)).subscribe(console.log);
  • 52.
  • 53.
    REACTIVE EXTENSIONS FORJAVASCRIPT CREATING AN OBSERVABLE import { of } from ‘rxjs'; import { map } from ‘rxjs/operators'; of(of(10), of(10)).pipe(switchMap(x => x), map(x => x + 100)).subscribe(console.log);
  • 54.
  • 55.
    WHAT ARE THEDIFFERENCES RXJS AND PROMISES?
  • 56.
    REACTIVE EXTENSIONS FORJAVASCRIPT CREATING AN OBSERVABLE STREAM (1) import { from } from ‘rxjs'; import { map } from ‘rxjs/operators'; const stream$ = from([1, 2, 3, 4]).pipe(map(x => x + 1)); stream$.subscribe(console.log) // > 2 // > 3 // > 4 // > 5
  • 57.
    REACTIVE EXTENSIONS FORJAVASCRIPT CREATING AN OBSERVABLE STREAM (2) import { interval } from ‘rxjs'; import { publish } from ‘rxjs/operators’; const connectableTimer = interval(1000).pipe(publish()); connectableTimer.connect(); setTimeout(function () { connectableTimer.subscribe(console.log); // > 4 // > 5 // > 6 // > 7 // ... }, 5000)
  • 58.
    REACTIVE EXTENSIONS FORJAVASCRIPT HOT AND COLD OBSERVABLES ▸ Cold - An observable is “cold” if its underlying producer is created and activated during subscription. ▸ Hot - An observable is “hot” if its underlying producer is either created or activated outside of subscription.
  • 59.
    1. OBSERVABLES ARE STREAMSOF DATA(One or more values)
  • 60.
    REACTIVE EXTENSIONS FORJAVASCRIPT COMMON THINGS THAT WE NEED ▸ debouncing ▸ cancelation ▸ retrying ▸ throttling ▸ timeouts ▸ detect only if something changed
  • 61.
  • 62.
    2. BETTER FLOWCONTROL (using the rxjs operators and rxjs observable factories/combiners)
  • 63.
    3. DIFFERENT WAYSOF EMITTING DATA (hot vs cold observables)
  • 64.
    4. OBSERVABLES ARECANCELLABLE (using unsubscribe)
  • 65.
    5. OBSERVABLES ARELAZY (we have to explicitly state that we want the observable to start)
  • 66.
  • 67.
    WHAT IS COMMONABOUT RXJS AND PROMISES?
  • 68.
    MARBLE TESTING RXJSSTREAMS WHAT IS COMMON ABOUT RXJS AND PROMISES? ▸ They are both monads like. ▸ Both are used to capture the effect of latency.
  • 69.
    WHY ARE THEYREACTIVE?
  • 70.
  • 71.
    MARBLE TESTING RXJSSTREAMS CONNECT GitHub > https://github.com/iliaidakiev (/slides/ - list of future and past events) Twitter > @ilia_idakiev
  • 72.