29
DA IMPERATIVO A REATTIVO: BACON.JS UGIDotNET – REBOOT Roberto Messora robymes [email protected]

Da imperativo a reattivo: Bacon.JS

Embed Size (px)

Citation preview

Page 1: Da imperativo a reattivo: Bacon.JS

DA IMPERATIVO A REATTIVO:

BACON.JSUGIDotNET – REBOOT

Roberto Messora

robymes

[email protected]

Page 2: Da imperativo a reattivo: Bacon.JS

Follow me live

Githubhttps://github.com/robymes/BaconJsPlayground

Slidesharehttp://www.slideshare.net/RobertoMessora/da-imperativo-a-reattivo-baconjs

Page 3: Da imperativo a reattivo: Bacon.JS

Agenda

■Functional Reactive Programming■Bacon.JS 1-2-3■Organizzazione di una solution■Da MV* a FRP: perchè?■Unit testing■Bacon.JS FAQ■Q&A

Page 4: Da imperativo a reattivo: Bacon.JS

Functional Reactive Programming■ FRP è un paradigma di programmazione che utilizza i tipici

building block della programmazione funzionale (map, reduce, filter, …)

■ I concetti chiave di FRP sono:– Modellazione di valori che cambiano con continuità nel tempo:

behaviors o signal– Modellazione di eventi che accadono in precisi momenti nel

tempo– Un sistema modifica il proprio stato in risposta ad eventi

(switching)– Separazione fra il modello reattivo e le modalità di campionatura

del sistema

Page 5: Da imperativo a reattivo: Bacon.JS

Bacon.JS

A small functional reactive programming lib for JavaScript.

Page 6: Da imperativo a reattivo: Bacon.JS

Bacon.JS 1-2-3

■ Bacon.JS è basato sul concetto di stream di eventi■ Uno stream è un oggetto immutabile e osservabile per cui si può

sottoscrivere l’evento di modifica del proprio valore■ Esistono 3 tipi di stream:

– EventStream– Property– Bus

■ EventStream e Property non si possono creare direttamente, bensì a partire da altre fonti/sorgenti

■ Bus è l’unica tipologia di stream inizializzabile tramite new Bacon.Bus()

Page 7: Da imperativo a reattivo: Bacon.JS

Evento di uno stream

■ Ogni evento di uno stream è istanza della classe Bacon.Event o di una delle sue sottoclassi: Bacon.Next, Bacon.End, Bacon.Error, Bacon.Initial

■ Ogni evento offre una API per accedere al suo stato:– event.value()– event.hasValue()– event.isNext()– event.isInitial()– event.isEnd()

■ In realtà raramente nella pratica si lavora direttamente con l’oggetto Event, bensì dirattamente con il suo valore (value)

Page 8: Da imperativo a reattivo: Bacon.JS

Semantica di uno stream

1. Quando un evento Next (prossimo) viene emesso, questo viene emesso a tutti i sottoscrittori

2. Quando un evento viene emesso, non verrà mai più emesso nuovamente nel futuro, al massimo può essere emesso un nuovo evento con lo stesso valore

3. Quando un nuovo sottoscrittore si registra ad uno stream riceve o meno un evento iniziale con l’ultimo valore a seconda che lo stream sia una Property (riceve l’evento) o un EventStream (non riceve l’evento)

4. Uno stream non può emettere alcun nuovo evento dopo l’emissione dell’evento End

Page 9: Da imperativo a reattivo: Bacon.JS

API di creazione stream

■ Bacon.JS offre una API molto ricca per la creazione di uno stream:– $.asEventStream, Bacon.fromEvent: da eventi DOM– Bacon.fromPromise: da promise (es. ajax)– Bacon.fromCallback– Bacon.fromPoll– Bacon.fromArray– Bacon.interval– …

Page 10: Da imperativo a reattivo: Bacon.JS

Sottoscrizione agli eventi di uno stream■ L’API di sottoscrizione è molto varia:

– observable.subscribe– observable.onValue, observable.onValues– observable.onError– observable.map– observable.filter– observable.take, observable.skip– …

Page 11: Da imperativo a reattivo: Bacon.JS

SHOW ME THE CODECreazione e sottoscrizione stream

https://github.com/robymes/BaconJsPlayground

Page 12: Da imperativo a reattivo: Bacon.JS

Da MV* a FRP: perchè?

■ Tutto è iniziato cercando una alternativa ai presentation framework MV* in realazione ad alcuni aspetti che creano “attrito”:– Una certa insoddisfazione di fondo rispetto ai motori di

templating del DOM (sintassi di data-binding): sporcano il markup in maniera spesso invasiva, a volte è difficile individuarne un errore a runtime

– I motori di data-bind native dei framework MV* spesso non sono ottimizzati per l’update del markup

– Oggettivamente il mondo del web là fuori è fatto di plug-in jQuery, la cui integrazione in un framework MV* non è sempre agevole

– Al crescere della complessità di una applicazione client non sempre si riesce a tenere il passo manutenendo una buona codebase

Page 13: Da imperativo a reattivo: Bacon.JS

Organizzazione di una solution

■ Anche con Bacon.JS è di fondamentale importanza organizzare correttamente una solution

■ Rimane valido il principio di separazione delle responsabilità:– View– Modello reattivo

■ La regola generale è quella di suddividere la UI e la sua logica di presentation in “widget” che espongono verso l’esterno e/o ricevono in input stream

Page 14: Da imperativo a reattivo: Bacon.JS

Baco.JS PlaygroundApp

TodoListView NewTodoItemView

TodoList

TodoListTableBuilder

NewTodoItemtodoItems

selectedTodoItem

newTodoItem

newTodoItemInModification

Page 15: Da imperativo a reattivo: Bacon.JS

SHOW ME THE CODEOrganizzazione di una solution

https://github.com/robymes/BaconJsPlayground

Page 16: Da imperativo a reattivo: Bacon.JS

Combinare stream

■Il cuore di una applicazione Bacon.JS è la capacità di poter combinare fra di loro diversi stream

■Il risultato di una qualsiasi combinazione è un nuovo stream

■È di fondamentale importanza comprendere che ogni stream è immutabile quindi gli stream componenti non vengono in alcun modo modificati

Page 17: Da imperativo a reattivo: Bacon.JS

API di combinazione stream

■ Dove Bacon.JS (ed FRP) davvero esprime tutta la sua potenza è nella possibilità di combinare fra loro due o più stream, generandone di nuovi (senza modificare quelli partecipanti alla combinazione)– Bacon.combineAsArray, Bacon.combineWith,

Bacon.combineTemplate– Bacon.mergeAll– Bacon.zipAsArray, Bacon.zipWith– Bacon.when– Bacon.update

Page 18: Da imperativo a reattivo: Bacon.JS

SHOW ME THE CODEBacon.update

https://github.com/robymes/BaconJsPlayground

Page 19: Da imperativo a reattivo: Bacon.JS

“La” domanda

Dove trovo il metodo getLatestValue di uno

stream?

Page 20: Da imperativo a reattivo: Bacon.JS
Page 21: Da imperativo a reattivo: Bacon.JS
Page 22: Da imperativo a reattivo: Bacon.JS

“La” risposta

Non esiste alcun metodo per accedere direttamente all’ultimo valore di uno

stream

■ Questo è FRP: non esiste il concetto di accesso diretto all’ultimo valore di uno stream

■ In FRP si parla di campionamento di uno stream di eventi

Page 23: Da imperativo a reattivo: Bacon.JS

SHOW ME THE CODECampionatura degli stream

https://github.com/robymes/BaconJsPlayground

Page 24: Da imperativo a reattivo: Bacon.JS

Unit testing

■ Perseguendo una netta separazione fra View e Modello Reattivo diventa molto semplice ed intuitivo impostare una strategia di Unit Testing sul Modello

■ Per quanto riguarda la UI rimane valida l’opzione di page automation testing con strumenti come Phantom.JS o Selenium

Page 25: Da imperativo a reattivo: Bacon.JS

SHOW ME THE CODEUnit Testing

https://github.com/robymes/BaconJsPlayground

Page 26: Da imperativo a reattivo: Bacon.JS

Bacon.JS FAQ

■ NO, non esiste getLatestValue!■ È stabile e pronto per produzione anche su larga scala?

– Assolutamente sì■ È performante?

– Non ci sono benchmark ufficiali, ma il creatore del framework asserisce che ci ha sviluppato un gioco totalmente basato su stream e non ha riscontrato problemi di utilizzo di memoria o rallentamenti nei vari browser utilizzati

– Usare nelle View un framework di Virtual DOM aiuta (Maquette, Velocity)■ È possibile integrare Bacon.JS con Pinco Pallino?

– Bacon.JS può essere usato a qualsiasi livello di integrazione con qualsiasi altro framework di presentation

Page 27: Da imperativo a reattivo: Bacon.JS

Q & A■Domande?

Page 28: Da imperativo a reattivo: Bacon.JS

Web App Testing Using Knockout.JSDesign, implement, and maintain a fully tested JavaScript web application using Knockout.JS

• Test JavaScript web applications using one of the most known unit testing libraries—Jasmine.js

• Leverage the two way bindings and dependency tracking mechanism to test web applications using Knockout.js

• The book covers different JavaScript application testing strategies supported by real-world examples

PacktPub

Page 29: Da imperativo a reattivo: Bacon.JS

Grazie

Roberto Messora

robymes

[email protected]

robymes