SlideShare ist ein Scribd-Unternehmen logo
1 von 47
Downloaden Sie, um offline zu lesen
@nicoespeon
À la découverte des
Observables
Meetup HumanTalks Paris Décembre 2017
1
@nicoespeon 2
@nicoespeon 3
@nicoespeon 4
Back-end
1
2
3
@nicoespeon 5
$search.on('click', () !=> {
fetchTrips()
.then(({data}) !=> renderFoundTrips(data))
.catch(handleError)
})
@nicoespeon 6
@nicoespeon 7
Back-end
1
3
2
4
Si c’est incomplet, on « poll »
@nicoespeon 8
$search.on('click', () !=> {
fetchTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
})
function renderFoundTripsAndPoll({data, isComplete}) {
renderFoundTrips(data)
if (!isComplete) {
pollTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}
}
@nicoespeon 9
@nicoespeon 10
Back-end
1
3
2
4
On optimise le polling
5s
@nicoespeon 11
$search.on('click', () !=> {
fetchTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
})
function renderFoundTripsAndPoll({data, isComplete}) {
const DELAY_BEFORE_POLLING_IN_MS = 5000
renderFoundTrips(data)
if (!isComplete) {
setTimeout(() !=> {
pollTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DELAY_BEFORE_POLLING_IN_MS )
}
}
@nicoespeon
« Et si on lançait la
recherche au fur et à
mesure de la saisie ? »
12
@nicoespeon 13
const DEBOUNCE_TIME_IN_MS = 250
let fetchTripsTimeout
$input.on('keypress', () !=> {
clear(fetchTripsTimeout)
fetchTripsTimeout = setTimeout(() !=> {
fetchTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DEBOUNCE_TIME_IN_MS);
})
function renderFoundTripsAndPoll({data, isComplete}) {
const DELAY_BEFORE_POLLING_IN_MS = 5000
renderFoundTrips(data)
if (!isComplete) {
setTimeout(() !=> {
pollTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DELAY_BEFORE_POLLING_IN_MS )
}
}
@nicoespeon 14
const DEBOUNCE_TIME_IN_MS = 250
let fetchTripsTimeout
$input.on('keypress', () !=> {
clear(fetchTripsTimeout)
fetchTripsTimeout = setTimeout(() !=> {
fetchTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DEBOUNCE_TIME_IN_MS);
})
function renderFoundTripsAndPoll({data, isComplete}) {
const DELAY_BEFORE_POLLING_IN_MS = 5000
renderFoundTrips(data)
if (!isComplete) {
setTimeout(() !=> {
pollTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DELAY_BEFORE_POLLING_IN_MS )
}
}
@nicoespeon 15
Back-end
1
2
3
Nous avons un bug…
4
Oups
@nicoespeon 16
@nicoespeon
Nicolas Carlo
17
@nicoespeon
Servez-vous des Observables
pour gérer des scénarios
asynchrones compliqués
18
@nicoespeon
Si on modélisait ça autrement ?
19
Un événement
Une erreur
Flux terminé
temps
= Observable
@nicoespeon
- Andre Staltz, 2 minute introduction to Rx
« Think of it as an
asynchronous
immutable array »
20
@nicoespeon
Utilisez les Observables avec ReactiveX
• Projet porté par Microsoft, en open-source depuis 2012
• Implémente les Observables dans de nombreux langages
(Java, Python, JS, .NET, Go, Ruby, Elixir, Swift…)
• Fournit une API pour manipuler des flux observables
21
@nicoespeon
Réfléchissez avec des diagrammes Marbles
22
http://rxmarbles.com/
@nicoespeon 23
@nicoespeon
clickStream ➜ click$
24
@nicoespeon
Fetch au click
25
flatMap
click$
fetchedTrips$
@nicoespeon 26
const fetchedTrips$ = fromEvent($search, 'click')
.flatMap(fetchTrips)
fetchedTrips$.subscribe(
({data}) !=> renderFoundTrips(data),
handleError
)
@nicoespeon
Le polling
27
flatMap
isRequestComplete$
polledTrips$
filter
@nicoespeon 28
const isRequestComplete$ = new Subject()
const fetchedTrips$ = fromEvent($search, 'click')
.flatMap(fetchTrips)
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.flatMap(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon
Le polling optimisé
29
flatMap
isRequestComplete$
polledTrips$
delay
@nicoespeon 30
const isRequestComplete$ = new Subject()
const fetchedTrips$ = fromEvent($search, 'click')
.flatMap(fetchTrips)
const DELAY_BEFORE_POLLING_IN_MS = 5000
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.delay(DELAY_BEFORE_POLLING_IN_MS )
.flatMap(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon
« Et si on lançait la
recherche au fur et à
mesure de la saisie ? »
31
@nicoespeon
Fetch au fur et à mesure
32
flatMap
keypress$
fetchedTrips$
debounce
@nicoespeon 33
const isRequestComplete$ = new Subject()
const DEBOUNCE_TIME_IN_MS = 250
const fetchedTrips$ = fromEvent($input, 'keypress')
.debounce(DEBOUNCE_TIME_IN_MS)
.flatMap(fetchTrips)
const DELAY_BEFORE_POLLING_IN_MS = 5000
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.delay(DELAY_BEFORE_POLLING_IN_MS )
.flatMap(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon 34
@nicoespeon
FlatMapLatest
35
reactivex.io/documentation/operators/flatmap.html
@nicoespeon 36
const isRequestComplete$ = new Subject()
const DEBOUNCE_TIME_IN_MS = 250
const fetchedTrips$ = fromEvent($input, 'keypress')
.debounce(DEBOUNCE_TIME_IN_MS)
.flatMapLatest(fetchTrips)
const DELAY_BEFORE_POLLING_IN_MS = 5000
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.delay(DELAY_BEFORE_POLLING_IN_MS )
.flatMapLatest(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon 37
const isRequestComplete$ = new Subject()
const DEBOUNCE_TIME_IN_MS = 250
const fetchedTrips$ = fromEvent($input, 'keypress')
.debounce(DEBOUNCE_TIME_IN_MS)
.flatMapLatest(fetchTrips)
const DELAY_BEFORE_POLLING_IN_MS = 5000
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.delay(DELAY_BEFORE_POLLING_IN_MS )
.flatMapLatest(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon
Qu’avons-nous gagné ?
✓ Code déclaratif, facile à faire évoluer
✓ Logique applicative sans effets de bords, facile à tester
✓ Observables composables, facile à ré-utiliser
38
@nicoespeon
L’usage des Observables se popularise dans le web
• Embarqué par défaut dans Angular
• Il y a des adaptations pour chaque librairie :
redux−observable, vue-rx…
• Cycle.js est un framework fonctionnel et réactif, basé sur
l’usage des Observables
39
@nicoespeon
Pensez aux Observables
pour résoudre vos
problèmes asynchrones
non triviaux
40
@nicoespeon 41
Bienvenue sur la route 

de la programmation réactive !
@nicoespeon
Pour aller plus loin
The introduction to Reactive Programming you've been missing
RxJS Functions with Examples
Using Observables in real life
Testing reactive code
📚 Reactive Programming - What is RxJS? (lessons)
🎦 The whole future declared in a var (video)
📑 Dynamics of Change - Why Reactivity matters (PDF)
🥋 Reactive Extensions (Rx.js) Workshop (kata)
42
@nicoespeon
Des diagrammes Marbles dans le code
43
const polledTrips$ = isRequestComplete$
!// !!---(true)----(false)----------(false)------->
.filter((isComplete) !=> !isComplete)
!// ------------(false)----------(false)-------->
.delay(DELAY_BEFORE_POLLING_IN_MS )
!// ----------------(false)----------(false)---->
.flatMapLatest(pollTrips)
!// ----------------(A)--------------(A)-------->
@nicoespeon
Analysons les strates du code
44
Gestion du temps (debounce, délai)
Logique applicative
Effets de bord (rendu, gestion des erreurs)
Évènements du DOM (click, keypress)
@nicoespeon 45
const DEBOUNCE_TIME_IN_MS = 250
let fetchTripsTimeout
$input.on('keypress', () !=> {
clear(fetchTripsTimeout)
fetchTripsTimeout = setTimeout(() !=> {
fetchTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DEBOUNCE_TIME_IN_MS);
})
function renderFoundTripsAndPoll({data, isComplete}) {
const DELAY_BEFORE_POLLING_IN_MS = 5000
renderFoundTrips(data)
if (!isComplete) {
setTimeout(() !=> {
pollTrips()
.then(renderFoundTripsAndPoll)
.catch(handleError)
}, DELAY_BEFORE_POLLING_IN_MS )
}
}
@nicoespeon 46
const isRequestComplete$ = new Subject()
const DEBOUNCE_TIME_IN_MS = 250
const fetchedTrips$ = fromEvent($input, 'keypress')
.debounce(DEBOUNCE_TIME_IN_MS)
.flatMapLatest(fetchTrips)
const DELAY_BEFORE_POLLING_IN_MS = 5000
const polledTrips$ = isRequestComplete$
.filter((isComplete) !=> !isComplete)
.delay(DELAY_BEFORE_POLLING_IN_MS )
.flatMapLatest(pollTrips)
const foundTrips$ = merge(fetchedTrips$, polledTrips$)
foundTrips$.subscribe(
({data, isComplete}) !=> {
renderFoundTrips(data)
isRequestComplete$.next(isComplete)
},
handleError
)
@nicoespeon 47
14 alternances
Effets de bords
couplés à la
logique applicative
6 alternances
Effets de bords
isolés

Weitere ähnliche Inhalte

Was ist angesagt?

Rのスコープとフレームと環境と
Rのスコープとフレームと環境とRのスコープとフレームと環境と
Rのスコープとフレームと環境とTakeshi Arabiki
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184Mahmoud Samir Fayed
 
The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185Mahmoud Samir Fayed
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionosfameron
 
Why learn new programming languages
Why learn new programming languagesWhy learn new programming languages
Why learn new programming languagesJonas Follesø
 
RxJava In Baby Steps
RxJava In Baby StepsRxJava In Baby Steps
RxJava In Baby StepsAnnyce Davis
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016Naoki Kitora
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere MortalsCurtis Poe
 
Best Java Problems and Solutions
Best Java Problems and SolutionsBest Java Problems and Solutions
Best Java Problems and SolutionsJava Projects
 
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...Jeroen Baten
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架jeffz
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperosfameron
 
The core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaThe core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaMite Mitreski
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)jeffz
 

Was ist angesagt? (20)

Rのスコープとフレームと環境と
Rのスコープとフレームと環境とRのスコープとフレームと環境と
Rのスコープとフレームと環境と
 
The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184The Ring programming language version 1.5.3 book - Part 10 of 184
The Ring programming language version 1.5.3 book - Part 10 of 184
 
The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185The Ring programming language version 1.5.4 book - Part 10 of 185
The Ring programming language version 1.5.4 book - Part 10 of 185
 
Functional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures editionFunctional Pe(a)rls - the Purely Functional Datastructures edition
Functional Pe(a)rls - the Purely Functional Datastructures edition
 
Why learn new programming languages
Why learn new programming languagesWhy learn new programming languages
Why learn new programming languages
 
ECMA5 and ES6 Promises
ECMA5 and ES6 PromisesECMA5 and ES6 Promises
ECMA5 and ES6 Promises
 
RxJava In Baby Steps
RxJava In Baby StepsRxJava In Baby Steps
RxJava In Baby Steps
 
JavaScript @ CTK
JavaScript @ CTKJavaScript @ CTK
JavaScript @ CTK
 
Scala kansai summit-2016
Scala kansai summit-2016Scala kansai summit-2016
Scala kansai summit-2016
 
Fp intro scala
Fp intro scalaFp intro scala
Fp intro scala
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
Hadoop I/O Analysis
Hadoop I/O AnalysisHadoop I/O Analysis
Hadoop I/O Analysis
 
Perl 6 For Mere Mortals
Perl 6 For Mere MortalsPerl 6 For Mere Mortals
Perl 6 For Mere Mortals
 
Best Java Problems and Solutions
Best Java Problems and SolutionsBest Java Problems and Solutions
Best Java Problems and Solutions
 
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
T-DOSE 2015: Using Python, PHP, JQuery and Linux to visualize the heartrate a...
 
响应式编程及框架
响应式编程及框架响应式编程及框架
响应式编程及框架
 
Welcome to python
Welcome to pythonWelcome to python
Welcome to python
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipper
 
The core libraries you always wanted - Google Guava
The core libraries you always wanted - Google GuavaThe core libraries you always wanted - Google Guava
The core libraries you always wanted - Google Guava
 
Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)Jscex: Write Sexy JavaScript (中文)
Jscex: Write Sexy JavaScript (中文)
 

Ähnlich wie Reactive Search with Observables

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
Implementing pattern-matching in JavaScript (full version)
Implementing pattern-matching in JavaScript (full version)Implementing pattern-matching in JavaScript (full version)
Implementing pattern-matching in JavaScript (full version)François-Guillaume Ribreau
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!Boy Baukema
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sRoel Hartman
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme SwiftMovel
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftFlorent Pillet
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tourSimon Proctor
 
Data visualization by Kenneth Odoh
Data visualization by Kenneth OdohData visualization by Kenneth Odoh
Data visualization by Kenneth Odohpyconfi
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Paulo Morgado
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeMario Gleichmann
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSRyan Anklam
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)riue
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on AndroidTomáš Kypta
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner codeMite Mitreski
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in HaskellHiromi Ishii
 

Ähnlich wie Reactive Search with Observables (20)

Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
Implementing pattern-matching in JavaScript (full version)
Implementing pattern-matching in JavaScript (full version)Implementing pattern-matching in JavaScript (full version)
Implementing pattern-matching in JavaScript (full version)
 
Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09Spl Not A Bridge Too Far phpNW09
Spl Not A Bridge Too Far phpNW09
 
Let's build a parser!
Let's build a parser!Let's build a parser!
Let's build a parser!
 
My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
 
Extreme Swift
Extreme SwiftExtreme Swift
Extreme Swift
 
Scala vs Ruby
Scala vs RubyScala vs Ruby
Scala vs Ruby
 
Reactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwiftReactive Programming Patterns with RxSwift
Reactive Programming Patterns with RxSwift
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
 
Data visualization by Kenneth Odoh
Data visualization by Kenneth OdohData visualization by Kenneth Odoh
Data visualization by Kenneth Odoh
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Empathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible codeEmpathic Programming - How to write comprehensible code
Empathic Programming - How to write comprehensible code
 
Add Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJSAdd Some Fun to Your Functional Programming With RXJS
Add Some Fun to Your Functional Programming With RXJS
 
A bit about Scala
A bit about ScalaA bit about Scala
A bit about Scala
 
関数潮流(Function Tendency)
関数潮流(Function Tendency)関数潮流(Function Tendency)
関数潮流(Function Tendency)
 
Reactive programming on Android
Reactive programming on AndroidReactive programming on Android
Reactive programming on Android
 
Google Guava for cleaner code
Google Guava for cleaner codeGoogle Guava for cleaner code
Google Guava for cleaner code
 
Metaprogramming in Haskell
Metaprogramming in HaskellMetaprogramming in Haskell
Metaprogramming in Haskell
 
SPL, not a bridge too far
SPL, not a bridge too farSPL, not a bridge too far
SPL, not a bridge too far
 

Mehr von Nicolas Carlo

The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureNicolas Carlo
 
Hexagonal architecture & Elixir
Hexagonal architecture & ElixirHexagonal architecture & Elixir
Hexagonal architecture & ElixirNicolas Carlo
 
À la découverte des observables
À la découverte des observablesÀ la découverte des observables
À la découverte des observablesNicolas Carlo
 
Testing Marionette.js Behaviors
Testing Marionette.js BehaviorsTesting Marionette.js Behaviors
Testing Marionette.js BehaviorsNicolas Carlo
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreNicolas Carlo
 
Les générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidienLes générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidienNicolas Carlo
 
Kanban et Game Development avec Trello
Kanban et Game Development avec TrelloKanban et Game Development avec Trello
Kanban et Game Development avec TrelloNicolas Carlo
 
Plop : un micro-générateur pour se simplifier la vie au quotidien
Plop : un micro-générateur pour se simplifier la vie au quotidienPlop : un micro-générateur pour se simplifier la vie au quotidien
Plop : un micro-générateur pour se simplifier la vie au quotidienNicolas Carlo
 
Tester ses Behaviors Marionette.js
Tester ses Behaviors Marionette.jsTester ses Behaviors Marionette.js
Tester ses Behaviors Marionette.jsNicolas Carlo
 
Chaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreChaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreNicolas Carlo
 
Comment organiser un gros projet backbone
Comment organiser un gros projet backboneComment organiser un gros projet backbone
Comment organiser un gros projet backboneNicolas Carlo
 

Mehr von Nicolas Carlo (11)

The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal Architecture
 
Hexagonal architecture & Elixir
Hexagonal architecture & ElixirHexagonal architecture & Elixir
Hexagonal architecture & Elixir
 
À la découverte des observables
À la découverte des observablesÀ la découverte des observables
À la découverte des observables
 
Testing Marionette.js Behaviors
Testing Marionette.js BehaviorsTesting Marionette.js Behaviors
Testing Marionette.js Behaviors
 
Chaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscoreChaining and function composition with lodash / underscore
Chaining and function composition with lodash / underscore
 
Les générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidienLes générateurs de code, pour se simplifier la vie au quotidien
Les générateurs de code, pour se simplifier la vie au quotidien
 
Kanban et Game Development avec Trello
Kanban et Game Development avec TrelloKanban et Game Development avec Trello
Kanban et Game Development avec Trello
 
Plop : un micro-générateur pour se simplifier la vie au quotidien
Plop : un micro-générateur pour se simplifier la vie au quotidienPlop : un micro-générateur pour se simplifier la vie au quotidien
Plop : un micro-générateur pour se simplifier la vie au quotidien
 
Tester ses Behaviors Marionette.js
Tester ses Behaviors Marionette.jsTester ses Behaviors Marionette.js
Tester ses Behaviors Marionette.js
 
Chaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscoreChaining et composition de fonctions avec lodash / underscore
Chaining et composition de fonctions avec lodash / underscore
 
Comment organiser un gros projet backbone
Comment organiser un gros projet backboneComment organiser un gros projet backbone
Comment organiser un gros projet backbone
 

Kürzlich hochgeladen

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 

Kürzlich hochgeladen (20)

WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 

Reactive Search with Observables

  • 1. @nicoespeon À la découverte des Observables Meetup HumanTalks Paris Décembre 2017 1
  • 5. @nicoespeon 5 $search.on('click', () !=> { fetchTrips() .then(({data}) !=> renderFoundTrips(data)) .catch(handleError) })
  • 7. @nicoespeon 7 Back-end 1 3 2 4 Si c’est incomplet, on « poll »
  • 8. @nicoespeon 8 $search.on('click', () !=> { fetchTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }) function renderFoundTripsAndPoll({data, isComplete}) { renderFoundTrips(data) if (!isComplete) { pollTrips() .then(renderFoundTripsAndPoll) .catch(handleError) } }
  • 11. @nicoespeon 11 $search.on('click', () !=> { fetchTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }) function renderFoundTripsAndPoll({data, isComplete}) { const DELAY_BEFORE_POLLING_IN_MS = 5000 renderFoundTrips(data) if (!isComplete) { setTimeout(() !=> { pollTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DELAY_BEFORE_POLLING_IN_MS ) } }
  • 12. @nicoespeon « Et si on lançait la recherche au fur et à mesure de la saisie ? » 12
  • 13. @nicoespeon 13 const DEBOUNCE_TIME_IN_MS = 250 let fetchTripsTimeout $input.on('keypress', () !=> { clear(fetchTripsTimeout) fetchTripsTimeout = setTimeout(() !=> { fetchTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DEBOUNCE_TIME_IN_MS); }) function renderFoundTripsAndPoll({data, isComplete}) { const DELAY_BEFORE_POLLING_IN_MS = 5000 renderFoundTrips(data) if (!isComplete) { setTimeout(() !=> { pollTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DELAY_BEFORE_POLLING_IN_MS ) } }
  • 14. @nicoespeon 14 const DEBOUNCE_TIME_IN_MS = 250 let fetchTripsTimeout $input.on('keypress', () !=> { clear(fetchTripsTimeout) fetchTripsTimeout = setTimeout(() !=> { fetchTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DEBOUNCE_TIME_IN_MS); }) function renderFoundTripsAndPoll({data, isComplete}) { const DELAY_BEFORE_POLLING_IN_MS = 5000 renderFoundTrips(data) if (!isComplete) { setTimeout(() !=> { pollTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DELAY_BEFORE_POLLING_IN_MS ) } }
  • 18. @nicoespeon Servez-vous des Observables pour gérer des scénarios asynchrones compliqués 18
  • 19. @nicoespeon Si on modélisait ça autrement ? 19 Un événement Une erreur Flux terminé temps = Observable
  • 20. @nicoespeon - Andre Staltz, 2 minute introduction to Rx « Think of it as an asynchronous immutable array » 20
  • 21. @nicoespeon Utilisez les Observables avec ReactiveX • Projet porté par Microsoft, en open-source depuis 2012 • Implémente les Observables dans de nombreux langages (Java, Python, JS, .NET, Go, Ruby, Elixir, Swift…) • Fournit une API pour manipuler des flux observables 21
  • 22. @nicoespeon Réfléchissez avec des diagrammes Marbles 22 http://rxmarbles.com/
  • 26. @nicoespeon 26 const fetchedTrips$ = fromEvent($search, 'click') .flatMap(fetchTrips) fetchedTrips$.subscribe( ({data}) !=> renderFoundTrips(data), handleError )
  • 28. @nicoespeon 28 const isRequestComplete$ = new Subject() const fetchedTrips$ = fromEvent($search, 'click') .flatMap(fetchTrips) const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .flatMap(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 30. @nicoespeon 30 const isRequestComplete$ = new Subject() const fetchedTrips$ = fromEvent($search, 'click') .flatMap(fetchTrips) const DELAY_BEFORE_POLLING_IN_MS = 5000 const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .delay(DELAY_BEFORE_POLLING_IN_MS ) .flatMap(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 31. @nicoespeon « Et si on lançait la recherche au fur et à mesure de la saisie ? » 31
  • 32. @nicoespeon Fetch au fur et à mesure 32 flatMap keypress$ fetchedTrips$ debounce
  • 33. @nicoespeon 33 const isRequestComplete$ = new Subject() const DEBOUNCE_TIME_IN_MS = 250 const fetchedTrips$ = fromEvent($input, 'keypress') .debounce(DEBOUNCE_TIME_IN_MS) .flatMap(fetchTrips) const DELAY_BEFORE_POLLING_IN_MS = 5000 const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .delay(DELAY_BEFORE_POLLING_IN_MS ) .flatMap(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 36. @nicoespeon 36 const isRequestComplete$ = new Subject() const DEBOUNCE_TIME_IN_MS = 250 const fetchedTrips$ = fromEvent($input, 'keypress') .debounce(DEBOUNCE_TIME_IN_MS) .flatMapLatest(fetchTrips) const DELAY_BEFORE_POLLING_IN_MS = 5000 const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .delay(DELAY_BEFORE_POLLING_IN_MS ) .flatMapLatest(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 37. @nicoespeon 37 const isRequestComplete$ = new Subject() const DEBOUNCE_TIME_IN_MS = 250 const fetchedTrips$ = fromEvent($input, 'keypress') .debounce(DEBOUNCE_TIME_IN_MS) .flatMapLatest(fetchTrips) const DELAY_BEFORE_POLLING_IN_MS = 5000 const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .delay(DELAY_BEFORE_POLLING_IN_MS ) .flatMapLatest(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 38. @nicoespeon Qu’avons-nous gagné ? ✓ Code déclaratif, facile à faire évoluer ✓ Logique applicative sans effets de bords, facile à tester ✓ Observables composables, facile à ré-utiliser 38
  • 39. @nicoespeon L’usage des Observables se popularise dans le web • Embarqué par défaut dans Angular • Il y a des adaptations pour chaque librairie : redux−observable, vue-rx… • Cycle.js est un framework fonctionnel et réactif, basé sur l’usage des Observables 39
  • 40. @nicoespeon Pensez aux Observables pour résoudre vos problèmes asynchrones non triviaux 40
  • 41. @nicoespeon 41 Bienvenue sur la route 
 de la programmation réactive !
  • 42. @nicoespeon Pour aller plus loin The introduction to Reactive Programming you've been missing RxJS Functions with Examples Using Observables in real life Testing reactive code 📚 Reactive Programming - What is RxJS? (lessons) 🎦 The whole future declared in a var (video) 📑 Dynamics of Change - Why Reactivity matters (PDF) 🥋 Reactive Extensions (Rx.js) Workshop (kata) 42
  • 43. @nicoespeon Des diagrammes Marbles dans le code 43 const polledTrips$ = isRequestComplete$ !// !!---(true)----(false)----------(false)-------> .filter((isComplete) !=> !isComplete) !// ------------(false)----------(false)--------> .delay(DELAY_BEFORE_POLLING_IN_MS ) !// ----------------(false)----------(false)----> .flatMapLatest(pollTrips) !// ----------------(A)--------------(A)-------->
  • 44. @nicoespeon Analysons les strates du code 44 Gestion du temps (debounce, délai) Logique applicative Effets de bord (rendu, gestion des erreurs) Évènements du DOM (click, keypress)
  • 45. @nicoespeon 45 const DEBOUNCE_TIME_IN_MS = 250 let fetchTripsTimeout $input.on('keypress', () !=> { clear(fetchTripsTimeout) fetchTripsTimeout = setTimeout(() !=> { fetchTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DEBOUNCE_TIME_IN_MS); }) function renderFoundTripsAndPoll({data, isComplete}) { const DELAY_BEFORE_POLLING_IN_MS = 5000 renderFoundTrips(data) if (!isComplete) { setTimeout(() !=> { pollTrips() .then(renderFoundTripsAndPoll) .catch(handleError) }, DELAY_BEFORE_POLLING_IN_MS ) } }
  • 46. @nicoespeon 46 const isRequestComplete$ = new Subject() const DEBOUNCE_TIME_IN_MS = 250 const fetchedTrips$ = fromEvent($input, 'keypress') .debounce(DEBOUNCE_TIME_IN_MS) .flatMapLatest(fetchTrips) const DELAY_BEFORE_POLLING_IN_MS = 5000 const polledTrips$ = isRequestComplete$ .filter((isComplete) !=> !isComplete) .delay(DELAY_BEFORE_POLLING_IN_MS ) .flatMapLatest(pollTrips) const foundTrips$ = merge(fetchedTrips$, polledTrips$) foundTrips$.subscribe( ({data, isComplete}) !=> { renderFoundTrips(data) isRequestComplete$.next(isComplete) }, handleError )
  • 47. @nicoespeon 47 14 alternances Effets de bords couplés à la logique applicative 6 alternances Effets de bords isolés