arquitecturas reactivas para front end

41
Javier Vélez Reyes @javiervelezreye [email protected] Arquitecturas Reac-vas de Streams Arquitecturas de Frontend Octubre 2014

Upload: javier-velez-reyes

Post on 07-Jul-2015

872 views

Category:

Software


0 download

DESCRIPTION

En los últimos tiempos se viene demandando dentro de las comunidades de desarrollo la construcción de arquitecturas reactivas que sean capaces de hacer frente a parámetros de rendimiento y tiempo de respuesta no conocidos hasta el momento. Una arquitectura reactiva es un sistema responsive capaz de reaccionar a tiempo a los requisitos bajo demanda, diseñado para adaptarse elásticamente a sus fluctuaciones variantes, que presenta un comportamiento altamente tolerante a fallos y que se dirige por un procesamiento masivo de mensajes. Pero más allá de todo esto, las arquitecturas reactivas se han convertido en un modelo de programación basado en transformaciones funcionales para dar soporte a sistemas dirigidos por eventos asíncronamente. En marco del desarrollo de soluciones para Front End, este tipo de aproximaciones está cogiendo tracción debido a lo bien que se adapta al modelo de interacción de la Web. En este contexto, los eventos responden a las interacciones del usuario sobre el agente navegador y la lógica de negocio se expresa como la transformación secuencial y progresiva de los mismos de forma encadenada. A lo largo de esta charla estudiaremos cómo funcionan este tipo de arquitecturas en contraposición con las clásicas soluciones MV* y presentaremos el modelo de desarrollo asociado.

TRANSCRIPT

Page 1: Arquitecturas Reactivas para Front End

JavierVélezReyes@javiervelezreye

[email protected]

ArquitecturasReac-vasdeStreams

ArquitecturasdeFrontend

Octubre2014

Page 2: Arquitecturas Reactivas para Front End

@javiervelezreye2

PresentaciónArquitecturasReac:vasdeStreams

Licenciado en informá2ca por la Universidad Politécnica deMadrid (UPM)desdeelaño2001ydoctoren informá2capor laUniversidad Nacional de Educación a Distancia (UNED) desde elaño2009,Javieresinves2gadoryestáespecializadoeneldiseñoy análisis de la colaboración. Esta labor la compagina conac2vidadesdeevangelización,consultoría,mentoringyformaciónespecializadaparaempresasdentrodelsectorIT.Inquieto,ávidolectoryseguidorcercanodelasinnovacionesentecnología.

I.¿QuiénSoy?

II.¿AQuéMeDedico? DesarrolladoFront/Back

EvangelizaciónWebArquitecturaSoVware

Formación&ConsultoríaITE-learning

DiseñodeSistemasdeColaboraciónLearningAnaly2cs

GamificaciónColabora2va

[email protected]

@javiervelezreye

linkedin.com/in/javiervelezreyes

gplus.to/javiervelezreyes

jvelez77

javiervelezreyes

youtube.com/user/javiervelezreyes

Page 3: Arquitecturas Reactivas para Front End

JavierVélezReyes@javiervelezreye

[email protected]

1Introducción§  LaWebComoModeloReac2vo§  Arquitecturascentradasenelmodelo§  ArquitecturasdeProgramaciónFuncionalReac2va§  PrincipiosdelasArquitecturasReac2vas

Introd

ucción

Arqu

itecturasRea

c-vasd

eStream

s

Page 4: Arquitecturas Reactivas para Front End

@javiervelezreye4

IntroducciónArquitecturasReac:vasdeStreams

A.LaWebComoModeloReac:vo

I.ElCaminoHacialasArquitecturasReac:vas

LaWeb,comoplataformadeinteracción,esunsistemareac2vo.ElárbolDOMquerepresentaenmemoriaeldocumentodelapáginaencursoesunmodelodedatossujetoacambiossobreelquepuedenregistrarsefuncionesescuchadorasparacadaunodeloseventosqueelsistemalanza como señalización de dichos cambios. La programación basada en escuchadores es elmásbásicoynucleardelosmodelosdeconstruccióndeaplica2vosWeb.

index.html

<button id='btn'> <button/>

Click

var btn = document.querySelector('#btn'); var sClicks = document.querySelector('#clicks'); var nClicks = 0; btn.addEventListener('click', function () { clicks.innerHTML = ++nClicks; });

Clicks: <span id="clicks"></span>

Page 5: Arquitecturas Reactivas para Front End

@javiervelezreye5

IntroducciónArquitecturasReac:vasdeStreams

B.ArquitecturasCentradasenelModelo

I.ElCaminoHacialasArquitecturasReac:vas

Como evolución del modelo de construcción basado en programación de escuchadores,emergieronunaseriedearquitecturasqueserecogenbajoelacrónicoMV*porsussimilitudesentresí.Todasellascompartenlapremisadequeestáncentradasenunmodelointernocuyoscambios son atendidos por la vista a través de cierta lógica de control. En general esteparaguasrecogediversasvariantesarquitectónicas.

Modelo

Vista Controlador

Usuario

man

ipulaactualiza

MVC

observa usa

Modelo

Adapter

Usuario

man

ipula

actualiza

MVA

observa usa

ModelViewController

El controlador manipula la vista enrespuesta a las interacciones delusuarioyelmodeloactualizalavista

ModelViewAdapter

Elmodelono se comunica con la vista.Es el adaptador el encargado depropagarloscambiosenambaspartes

Vista

Page 6: Arquitecturas Reactivas para Front End

@javiervelezreye6

IntroducciónArquitecturasReac:vasdeStreams

B.ArquitecturasCentradasenelModelo

I.ElCaminoHacialasArquitecturasReac:vas

Como evolución del modelo de construcción basado en programación de escuchadores,emergieronunaseriedearquitecturasqueserecogenbajoelacrónicoMV*porsussimilitudesentresí.Todasellascompartenlapremisadequeestáncentradasenunmodelointernocuyoscambios son atendidos por la vista a través de cierta lógica de control. En general esteparaguasrecogediversasvariantesarquitectónicas.

M

V C

HMVC

Modelo

Presenter

Usuario

man

ipula

actualiza

MVP

observa usa

ModelViewControllerJerárquico

LosmodelosMVCsedistribuyenentreelaplicaCvoparacadacomponentequeseorganizanagregaCvamente

ModelViewPresenter

ComoextensióndelMVA,elpatrónMVPhacequeelcontroladorsemantengaalasescuchadeloscambiosenlavistayelmodelo

M

V C

M

V C

Vista

Page 7: Arquitecturas Reactivas para Front End

@javiervelezreye7

IntroducciónArquitecturasReac:vasdeStreams

B.ArquitecturasCentradasenelModelo

I.ElCaminoHacialasArquitecturasReac:vas

Como evolución del modelo de construcción basado en programación de escuchadores,emergieronunaseriedearquitecturasqueserecogenbajoelacrónicoMV*porsussimilitudesentresí.Todasellascompartenlapremisadequeestáncentradasenunmodelointernocuyoscambios son atendidos por la vista a través de cierta lógica de control. En general esteparaguasrecogediversasvariantesarquitectónicas.

ModelViewView-Model

La vista y el modelo de vista permanecensincronizadosa travésdeunaarquitecturadeobservadoresymutadores

Vista ModelodeVista

Usuario

MVVM

Observa&interacciona

Databinding

Modeloactualiza

Page 8: Arquitecturas Reactivas para Front End

@javiervelezreye8

IntroducciónArquitecturasReac:vasdeStreams

C.ArquitecturasdeProgramaciónFuncionalReac:va

I.ElCaminoHacialasArquitecturasReac:vas

Encontraposicióna laspropuestasanterioresquear2culan su funcionamientoenbaseaunprocesodeescuchay transformacióndeunmodelodedatos internomásomenosexplicitoquerepresentaelestadodelaaplicaciónaparecenlasarquitecturasdeprogramaciónreac2vadondeloseventossonges2onadosporcadenasdetransformaciónfuncionalqueseencargandeprocesarlainteraccióndelusuariodeunamaneradeclara2va,inmutableysinestado.

index.html

<button id='btn'> <button/>

Click

Clicks: <span id="clicks"></span>

CadenadeTransformaciónFuncional

LoseventossonrecogidosdelaplataformaWeby se les hace atravesar una cadena detransformaciones funcionalesparaprocesar losresultados

Page 9: Arquitecturas Reactivas para Front End

@javiervelezreye9

IntroducciónArquitecturasReac:vasdeStreams

A.DirigidaporlosDatos

II.PrincipiosdeProgramaciónReac:va

Las arquitecturas de programación funcional reac2va definen cadenas de transformaciónfuncionalquesonatravesadasporflujosdedatosparasuprocesamiento.Sedicequeeste2podesolucionesestádirigidaporlosdatosporqueenellosdescansagranpartedelalógicadelaaplicaciónyelpropiocomportamientoreac2vodelsistema.

Click

click, click, click...

filter

group

take(10)

f

CadenadeTransformación

La cadena de transformación filtra los eventosde usuario, los agrupa por pares si éstos seproducen con cierta frecuencia temporal pararepresentar el doble click yfinalmenteabsorbesólolos10primeros

Comportamientodirigidopordatos

Lanaturalezade losdatosatravesadospor la cadena de transformacióncondicionacuándoseejecutaráf

Page 10: Arquitecturas Reactivas para Front End

@javiervelezreye10

IntroducciónArquitecturasReac:vasdeStreams

B.CentradaenlaComposición

II.PrincipiosdeProgramaciónReac:va

Las operacionesque formanpartedel procesamientodedatos enprogramación reac2va seencadenan de forma composi2va demanera que el resultado de cada transformación es laentrada para la siguiente transformación. Para poder ar2cular adecuadamente estacomposicióndebemostenerencuentadosreglasdetransformaciónfuncional.

ElCpodel parámetrodeentradadeuna funcióndebesercompaCbleconelCpodelvalorderetornodevueltopor la funciónanteriorparaque lacomposiciónpuedaarCcularse con éxito. Las arquitecturas reacCvastambién cumplen este requisito puesto que recibeneventoscomoentradaygeneraneventosdesalida

II.Compa:bilidadRango-Dominio

I.DominioSimpleDado que las funciones devuelven un único valor deretorno, el númerodeparámetrosde entradaquepuedeaceptar una función en una composición debe serexactamenteuno.EnelcasodelaprogramaciónreacCva,la información se encapsula en una estructura de datosque representa un evento lo que permite cumplir estacondición

F

GT

U

ElCpodesalidaTdebesercompaCbleconel Cpo de entrada U. En términos OOPdiríamosqueTdebesersubCpodeU

filter

group

f

event

Page 11: Arquitecturas Reactivas para Front End

@javiervelezreye11

IntroducciónArquitecturasReac:vasdeStreams

C.TransparenciaReferencial

II.PrincipiosdeProgramaciónReac:va

Elprincipiodetransparenciareferencialpredicaqueentodaespecificaciónfuncionalcorrecta,cualquierfuncióndebepodersubs2tuirseencualquierámbitodeaplicaciónporsuexpresiónfuncionalsinqueelloafectealresultadoobtenido.Equivalentemente,estoimplicaqueelvalorderetornodelasfunciones,comocualquiertransformaciónmatemá2ca,sólopuededependerdesusparámetrosdeentradaynodecondicionesambientales.

f

Estado FuncionesPuras

Se dice que las operaciones de transformaciónsonfuncionespurasentantoquegaranCzanelmantenimiento de la transparencia referencial.Así, su valor de retorno sólo depende de losparámetros de entrada y no del estadoambiental (variables globales, variablesretenidasenámbito léxico,operacionesdeE/S,etc.)

Page 12: Arquitecturas Reactivas para Front End

@javiervelezreye12

IntroducciónArquitecturasReac:vasdeStreams

D.ComportamientoIdempotente

II.PrincipiosdeProgramaciónReac:va

Unprincipioenestrecharelaciónconeldetransparenciareferencialesdedecomportamientoidempotente segúnel cual cada funciónde transformacióndebedevolver siempreelmismoresultado para los mismos parámetros de entrada. Esto permite razonar algebraicamentesobrelavalidezdelprocesamientoreac2vo.

La operación filter se encarga de dejarpasar a la cadena composiCva sóloaquellos eventos en los que x Cene unvalor par. Se trata de una operaciónidempotenteporqueparaelmismoeventodeentradasiempreprocedeigual

filter ( x es par )

scan (0)

f

OperaciónIdempotente

La operación scan cuenta el número deeventos que atraviesan la atraviesa ydevuelve un evento con el valor de dichocontador en cada invocación. Se trata deuna operación no idempotente porque elvalor devuelto depende del número deinvocacionesanteriores

OperaciónNoIdempotente

Page 13: Arquitecturas Reactivas para Front End

@javiervelezreye13

IntroducciónArquitecturasReac:vasdeStreams

E.InmutabilidaddeDatos

II.PrincipiosdeProgramaciónReac:va

Unúl2moprincipioheredadodelaprogramaciónfuncionalquedebemostenerencuentaenla construcción de arquitecturas reac2vas es el principio de inmutabilidad de datos. Entérminosprác2coslaaplicaciónseesteprincipiosetraduceenquelasfuncionesnuncadebenactualizarlosparámetrosdeentradacomoresultadodesuejecuciónsinosolamentegenerarapar2rdeellosresultadosdesalida.

Los eventos que atraviesan lafunción f son transformadospara generar un resultado desalida

FunciónMutadora

function f(e) { e.value = e.value + 10; return e; }

FunciónNoMutadora

function f(e) { var ne = new Event (e); ne.value = ne.value + 10; return ne; }

Paranomodificareleventoa laentrada, la función f construyeuna nueva copia delmismo y lotransforma para generar elresultadodesalida

Page 14: Arquitecturas Reactivas para Front End

JavierVélezReyes@javiervelezreye

[email protected]

2ConceptosEsenciales

§  ArquitecturasWebReac2vas§  VisiónEstá2ca§  VisiónDinámica

Concep

tosE

senciales

Arqu

itecturasRea

c-vasd

eStream

s

Page 15: Arquitecturas Reactivas para Front End

@javiervelezreye15

ConceptosEsencialesArquitecturasReac:vasdeStreams

Laprogramaciónfuncionalreac2vaesunmodelodeprogramaciónquepretendedarrespuestaalademandacrecientedenuevossistemasmásflexibles,elás2cosytolerantesafallosapar2rde los principios propios de la programación funcional. Esta aproximación resulta muyventajosa en tanto que produce desarrollos más declara2vos y explícitos centrados en lastransformacionesquedebensufrirlosdatosparasuprocesamiento.

I.ArquitecturasWebReac:vas

Las Arquitectura Web Reac-vas son sistemas soaware queoperanen reaccióna los eventosocurridos sobreelmodelodedatos DOM de laWeb. Cada evento atraviesa una cadena detransformaciónfuncionalparasuprocesamiento.

La lógica de negocio de una arquitecturareacCva queda capturada en la cadena detransformaciones que es atravesada por cadaevento.Estastransformacionessonengeneralinmutables, idempotentes y agnósCcas de lascondicionesambientales

I.ConstrucciónComposi:vaParadójicamente, las operaciones detransformación que arCculan las arquitec-turas reacCvas están en estrecha relacióncon el Cempo ya que éste es un factordeterminantealahoradeconstruirmodelosdecomportamientoreacCvo

II.ModeladoExplicitodelTiempo

Page 16: Arquitecturas Reactivas para Front End

@javiervelezreye16

ConceptosEsencialesArquitecturasReac:vasdeStreams

Desde un punto de vista estructural, las arquitecturas de programación funcional reac2vaestán caracterizadas por una colección de abstracciones funcionales. Estas abstracciones seencadenan secuencialmente para que lleven a cabo las tareas de procesamiento ytransformacióndeeventosdesdelafuenteemisoraalossumiderosreceptoresdemaneraquetodalalógicadenegocioseexpresadeformadeclara2vaydistribuidaalolargodelacadena.

II.VisiónEstá:ca

FuenteLafuentees laencargadadeproporcionar loseventosa lacadenadetransformación

CadenadeTransformaciónLas operaciones de transfor-mación funcional se enca-denancomposiCvamente

SumideroAl final de cada cadena se puedencolocar receptores que recogen losdatos procesados e incluso puedenmezclarseconotrascadenas

TransformaciónCadaoperacióndentrodelacadenaes una transformación funcional nomutadora

StreamdeEventosLos eventos provenientes de lafuente de datos fluyen discrecional-mentealolargodelCempo

Page 17: Arquitecturas Reactivas para Front End

@javiervelezreye17

ConceptosEsencialesArquitecturasReac:vasdeStreams

A.LíneadeTiempo

III.VisiónDinámica

Elcomportamientodelasarquitecturasreac2vasdeprogramaciónfuncionalseencuentraenestrecharelaciónconelfactor2empo.Enefecto,lalógicadelasoperacionesqueformanpartedelacadenadetransformacióndependecomúnmentedeaspectostalescomoelnúmerodeeventosprocesadoshastaelmomento,sufrecuenciadeapariciónosuperiodo.Estopermitemodelarfácilmentecomportamientossistémicosquedependendel2empo.

Cada evento ocupa unaposiciónsobrelalíneadeCempos

EventoLos streams también pueden generarerrores que se capturan y gesConancomoeventosespeciales

Error

Indica la terminación de lallegada y procesamiento deeventosporpartedelstream

TerminaciónRepresenta el histórico deeventosenunprocesamientode eventos. La punta deflecha indica el momentoactual

Líneade:empo

Page 18: Arquitecturas Reactivas para Front End

@javiervelezreye18

ConceptosEsencialesArquitecturasReac:vasdeStreams

B.DiagramasdeReac:vidad

III.VisiónDinámica

La mejor manera de razonar sobre las arquitectura reac2vas es por medio del uso dediagramasdereac2vidad.Undiagramadereac2vidadesunarepresentaciónalternadelíneasde2empoyoperacionesdetransformaciónfuncional.Cadaunadeestasoperacionesrecibecomoentradalalíneade2empoanteriorygeneracomosalidalalíneasubsiguiente.

clicks

groups

size3 2 1

Doubleclick3 2

Cada operación recibeuna línea de Cempocomoentradaygeneraasu salída otra línea deCempo con eventosnuevos

OperacionesCadalíneaesunaproyecciónalo largo del Cempo de lo queocurre en el sistema en unpunto determinado de lacadena

LíneasdeTiempo

buffer(throdle(250ms))

map(getlengthofgroup)

filter(size>1)

Page 19: Arquitecturas Reactivas para Front End

@javiervelezreye19

ConceptosEsencialesArquitecturasReac:vasdeStreams

B.DiagramasdeReac:vidad

III.VisiónDinámica

Los diagramas de reac2vidad ofrecen una visión del comportamiento de las arquitecturasreac2vasentornoadosperspec2vasortogonales.Encadaver2calsepuedecomprobarcuálesel proceso de transformación que sufre un evento en un momento del 2empo.Horizontalmente,secontemplaelcomportamientodecadafasealolargodel2empo

clicks

groups

size

Doubleclick

Se razona sobre lo queocurreenuninstantedeCempo con el procesa-miento de un eventoconcretoalo largodelacadena

DimensiónVer:cal

Se razona acerca de cómo secomporta cada fase y elproceso independientementedeladimensiónCempo

DimensiónHorizontal

3 2 1

3 2

buffer(throdle(250ms))

map(getlengthofgroup)

filter(size>1)

Page 20: Arquitecturas Reactivas para Front End

@javiervelezreye20

ConceptosEsencialesArquitecturasReac:vasdeStreams

C.OperacionesReac:vas

III.VisiónDinámica

Para completar la descripción del comportamiento dinámico es necesario conocer lasprincipalesoperacionesquepuedenaplicarseparadefinircadenasdetransformación.Elléxicode lasmismas cambia de una librería a otra pero en esencia todas proporcionan elmismojuegodefacilidadesdeclara2vas.

OperacionesdeCreaciónLas operaciones de creación permiten creardisCntas fuentes de eventos en relación adisCntosorígenesasíncronosdedatos

subscribe(f)

OperacionesdeTerminaciónLas operaciones de terminación permitendefinir sumideros al final de una cadenareacCva

stream(css)

values(interval,v)

serie(delay,it)

error(f)

end(f)

Page 21: Arquitecturas Reactivas para Front End

@javiervelezreye21

ConceptosEsencialesArquitecturasReac:vasdeStreams

C.OperacionesReac:vas

III.VisiónDinámica

Para completar la descripción del comportamiento dinámico es necesario conocer lasprincipalesoperacionesquepuedenaplicarseparadefinircadenasdetransformación.Elléxicode lasmismas cambia de una librería a otra pero en esencia todas proporcionan elmismojuegodefacilidadesdeclara2vas.

OperacionesdeMezcladeStreamsLasoperacionesdeentrelazadoymezcladestreamsdeeventospermiten fusionarvariosstreamsdeeventosparacrearstreamsdeeventoscompuestos.Estopermitequeunmismostreampuedaserprocesadopormásdeunacadenadecomposicióndeformasimultanea

concat

41

532 76

541 76

merge

41

532

321 54

startWith(v)

v

432

32v 54

5

Page 22: Arquitecturas Reactivas para Front End

@javiervelezreye22

ConceptosEsencialesArquitecturasReac:vasdeStreams

C.OperacionesReac:vas

III.VisiónDinámica

Del capítulo anterior ya ha quedado patente que las arquitecturas reac2vas presentan unaclara formulación funcional. Se trata en esencia de definir cadenas de transformación queserán atravesadas por los datos según van generándose. Sin embargo en términos másprác2cosexistenunaseriedecarácterís2casdiferencialesqueresumimosacon2nuación.

OperacionesdeGes:ónTemporalLas operaciones de gesCón del Cempo permiten modelarcomportamientosreacCvosqueCenenencuentacondicionestemporalesen relación a los eventos. Dado que estas funciones dependen de lascondicionesambientalesyfrecuentementenoCenenuncomportamientoidempotente su ajuste al paradigma funcional queda un poco enentredicho.

3 2 7 9

3 2 7 9

hold(<5)

3 2 7 9

7 9

skip(2)

3 2 7 9

3 2

take(2)

3 2 7 9

3 2 7 9

delay(10ms)

throdle(5ms)

Page 23: Arquitecturas Reactivas para Front End

@javiervelezreye23

ConceptosEsencialesArquitecturasReac:vasdeStreams

C.OperacionesReac:vas

III.VisiónDinámica

Del capítulo anterior ya ha quedado patente que las arquitecturas reac2vas presentan unaclara formulación funcional. Se trata en esencia de definir cadenas de transformación queserán atravesadas por los datos según van generándose. Sin embargo en términos másprác2cosexistenunaseriedecarácterís2casdiferencialesqueresumimosacon2nuación.

OperacionesdeSecuenciamientoLasoperacionesclásicasdesecuenciamiento(map, reduce, filter) se adaptan al modelounitariodeprocesamientoreacCvo

map(f) filter(f)

3

3

4

7

scan(0,+)

OperacionesdeAsincroníaLas operaciones asíncronas permitengesConar disCntos aspectos relacionadosconelcarácterasíncronodeloseventos

3 4

7

reduce(0,+)

map(p)

p

vp

v

flatMap(p)

Page 24: Arquitecturas Reactivas para Front End

JavierVélezReyes@javiervelezreye

[email protected]

3UnFrameworkSencillodeProgramaciónReac-va

§  ModelosdeProgramaciónReac2va§  FrameworkSencillodeProgramaciónReac2va§  Evaluación

UnFram

eworkSencillode

Program

aciónRe

ac-v

a

Arqu

itecturasRea

c-vasd

eStream

s

Page 25: Arquitecturas Reactivas para Front End

@javiervelezreye25

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

A.ModelosdeOperaciónPull&Push

I.ModelosdeProgramaciónReac:va

Es posible caracterizar las arquitecturas de programación funcional reac2va en virtud de lanaturalezasíncronaoasíncronadelosdatosqueprocesan.EllodalugarasendosmodelosdeoperaciónconocidosconelnombredePullyPushrespec2vamente.Enelprimercaso,eselsumidero el que pide nuevos datos a la cadenamientas que en el segundo es la fuente laencargadadeempujardichosdatosproac2vamenteencuantoéstossongenerados.

I.ModeloPullEn el modelo pull, el sumidero solicita nuevosdatos y la solicitud recorre ascendentemente lacadenahastallegaralafuente

La fuentees laenCdadpasivaquegeneranuevosdatosbajodemanda

I.ModeloPushEnelmodelopush,amedidaquesedisponendenuevosdatos,lafuentelosempujaporlacadenadetransformaciónhaciaabajo

La fuente es la enCdad acCvaque produce datos y losentregaalacadena

El sumidero es la enCdadacCva que pide a la cadenanuevosdatosprocesadosparaserconsumidos

El sumidero es una enCdadpasiva que se manCene a laescucha para consumir datoscuandollegandesdelacadena

Page 26: Arquitecturas Reactivas para Front End

@javiervelezreye26

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

B.ModelosdeComputaciónCon:nua&Discreta

I.ModelosdeProgramaciónReac:va

Ortogonalmente,lasfuentestambiénpuedenclasificarseenvirtuddelanaturalezacon2nuaodiscreta de los datos que procesan. En el primer caso, hablamos demodelos de streamimgdonde losdatossonseñalescon2nuasyperdurablesmientrasqueenel segundocaso,cadadato representaunaocurrenciapuntualenel2empoyelloconformaarquitecturasdirigidasporeventos.

I.ModeloCon:nuoEnelmodelodecomputaciónconCnualosdatossecorrespondenconstreamsllamadosseñalesocomportamientos

Los sistemas reaccionan a loscambiosenelflujodedatos.Aestecambiose lesuele llamarswitching. En este Cpo desistemas la frecuencia demuestreo es uno de losparámetroscaracterísCcos

I.ModeloDiscretoEnelmodelodiscreto losdatos secorrespondencon eventos que se producen en instantespuntualesdelCempo

Los eventos son elementosvehiculares que acarreanvalores de contexto transfor-mados a través de la cadenareacCva

Page 27: Arquitecturas Reactivas para Front End

@javiervelezreye27

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

C.Clasificación

I.ModelosdeProgramaciónReac:va

Es posible establecer las dos caracterizaciones anteriores como dos ejes dimensionalesdispuestos ortogonalmente. Ello da lugar a un espacio de clasificación que divide lasarquitecturas reac2vas en cuatro familias. Nosotros centraremos nuestra atención enarquitecturasWebreac2vas.

ModelosCon:nuosBasadosenStreams

ModelosDiscretosBasadosenEventos

Mod

elosSíncron

os

Mod

oPu

llMod

elosAsíncrono

sMod

oPu

sh ProgramaciónWebReac:va

BigDataEventProcessing

ModelodeActores

WebSockets

Iteradores&Generadores

ColeccionesInfinitas

EvaluaciónPerezosa

SignalProcessing

NoiseGenerators

Streammingdedatos

Video&AudioStreams

WebAudioAPI

WebRTC

Page 28: Arquitecturas Reactivas para Front End

@javiervelezreye28

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

A.GeneracióndeFuentes

II.FrameworkSencillodeProgramaciónReac:va

Como hemos visto en el capítulo anterior existe una gran variedad de constructores quepermitendefinir fuentes asíncronasque funcionanenmodoPush.Aquínos centraremosenpresentarelcódigointernodelasmáscomúnmenteu2lizadas.

AdaptadordeEventoWebLos adaptadores de eventos son funcionesque recogen eventosWeb y los redirigen auna función manejadora pasada comoargumento en una segunda fase deevaluaciónEn este ejemplo se ve cómo la funciónfromTarget construye una fuente s a parCrdeunselectorcssyunCpodeevento

function fromTarget(css, type) { var target = document.querySelector (css); return function (fn) { target.addEventListener(type, function (e) { fn(e); }); }; } function fromTargetAll(css, type) { var targets = document.querySelectorAll (css); return function (fn) { [].forEach.call(targets, function (target) { target.addEventListener(type, function (e) { fn(e); }); }); }; }

<button id="btn">click</button> ... <script> var s = fromTarget('#btn', 'click'); s(console.log); </script>

Page 29: Arquitecturas Reactivas para Front End

@javiervelezreye29

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

A.GeneracióndeFuentes

II.FrameworkSencillodeProgramaciónReac:va

Como hemos visto en el capítulo anterior existe una gran variedad de constructores quepermitendefinir fuentes asíncronasque funcionanenmodoPush.Aquínos centraremosenpresentarelcódigointernodelasmáscomúnmenteu2lizadas.

AdaptadordeColecciónLos adaptadores de colección persiguengenerar fuentes push que iteran circular-mentesobreloselementosdeunacolecciónaintervalosregularesdeCempoLa función fromValues recibe un array devaloresyunintervalodeCempoyconstruyeuna función que emiCrá un evento con elvalorsiguienteen lacoleccióncadavezqueesinvocado

function fromValues (values, ms) { return function (fn) { var idx = 0; var hn = fn || function () {}; setInterval (function () { fn(values[idx]); idx = (idx + 1) % values.length; }, ms || 1000); }; }

var s = fromValues([1,2,3]); s(console.log);

En este sencillo ejemplo, la construcción de lafuenteasíncronadeeventosemitecircularmente,aintervalos regulares de 1 segundo, los elementosdelarraypasadocomoparámetrodeentrada. Loseventos se vinculan al escuchador de salidaestándar

Page 30: Arquitecturas Reactivas para Front End

@javiervelezreye30

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

A.GeneracióndeFuentes

II.FrameworkSencillodeProgramaciónReac:va

Como hemos visto en el capítulo anterior existe una gran variedad de constructores quepermitendefinir fuentes asíncronasque funcionanenmodoPush.Aquínos centraremosenpresentarelcódigointernodelasmáscomúnmenteu2lizadas.

AdaptadordeIteraciónLa función serie toma una función genérica fn ydevuelve otra función iteradora que genera valoresconsecuCvosaplicandodichafunciónfromSerie es una fuente push que invoca la seriepasada como parámetro a intervalos regulares deCempo.EstaesunamaneradehacerunadaptadorPushsobreunafuentePullElcódigodeejemplodefinelafunciónincysobreellagenera laseriedenúmerosnaturalesnum.Despuesconstruyeunafuenteylavinculaalasalidaestándar

function serie (fn, base) { var value = base; return function () { value = fn(value); return value; }; } function fromSerie (serie, ms) { return function (fn) { var hn = fn || function () {}; setInterval (function () { var value = serie(); fn(value); }, ms || 1000); }; }

var inc = function (x) { return x + 1; } var num = serie(inc, 0); var s = fromSerie(num, 3000); s(console.log);

Page 31: Arquitecturas Reactivas para Front End

@javiervelezreye31

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

B.OperadoresdeTransformación

II.FrameworkSencillodeProgramaciónReac:va

Hastaahoradamossoportealadefinicióndefuentesdediferentes2posqueseconectanenmodoPushasumiderosdirectamente.Definamosacon2nuación,lacoleccióndeoperadoresdetransformaciónquepodránseru2lizadosparadefinircadenasennuestroframework.

OperadormapEl operador map es una función de orden superiorquerecibecomoparámetrounafunciónfngenéricay devuelve otra función como resultado. Elcomportamientodedichafunciónesinvocarafnconlos argumentos pasados como parámetro en estafunciónderetornoEl siguiente código de ejemplo muestra un usoprotoipico de la funciónmapque transforma cadadatodeentradaensucuadrado.Paraelloseaplicamap con una función anónima que define elcuadradoyluegoseaplicalafunciónresultante

function map (fn) { return function () { return fn.apply(this, arguments); }; }

var sqr = map(function (x) { return x * x; }); sqr(3); // 9

0

1

1

1

2

4

3

9

map(x=>x*x)

Page 32: Arquitecturas Reactivas para Front End

@javiervelezreye32

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

B.OperadoresdeTransformación

II.FrameworkSencillodeProgramaciónReac:va

Hastaahoradamossoportealadefinicióndefuentesdediferentes2posqueseconectanenmodoPushasumiderosdirectamente.Definamosacon2nuación,lacoleccióndeoperadoresdetransformaciónquepodránseru2lizadosparadefinircadenasennuestroframework.

OperadorfilterEl operador filter recibe un predicado lógico comoparámetroygeneraotrafuncióncomoretornocuyopropósito es filtrar sólo aquellos argumentos quesaCsfagandichopredicado.SielfiltronoespasadoentonceslafuncióndevuelveundefinedEn el ejemplo siguiente se aplica el operador filtersobreunpredicadológicoquedeterminasiunvalores par. El resultado es una función que sólo dejafiltrarloseventosconvalorpar.

function filter (fn) { return function () { var out = fn.apply (this, arguments); if (out) return arguments[0]; }; }

var even = filter(function (x) { return x % 2 === 0; }); even(2); // 2 even(3); // undefined

0

1

1 2

2

3

filter(x=>x%2===0)

Page 33: Arquitecturas Reactivas para Front End

@javiervelezreye33

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

B.OperadoresdeTransformación

II.FrameworkSencillodeProgramaciónReac:va

Hastaahoradamossoportealadefinicióndefuentesdediferentes2posqueseconectanenmodoPushasumiderosdirectamente.Definamosacon2nuación,lacoleccióndeoperadoresdetransformaciónquepodránseru2lizadosparadefinircadenasennuestroframework.

OperadorscanEloperadorscanesunoperadorconmemoria.Cadanuevodato locombinaconunacumuladorretenidoen ac a través de una función binaria de reducciónpasada como parámetro. El valor inicial delacumulador sepasacomosegundoparámetrobdelafunciónEn el ejemplo adjunto se aplica el operador scansobrelafunciónreductoradelasumayconbaseen0. Como resultado, cada evento devuelve la sumaacumuladadelosvaloresenloseventosprocesadoshastaelmomento

function scan (fn, b) { var ac = b; return function () { var args = [].slice.call (arguments); ac = fn.apply (this, [ac].concat(args)); return ac; }; }

var add = scan(function (x, y) { return x + y; }, 0); add(2); // 2 = 2 + 0 add(3); // 5 = 3 + 2 add(4); // 9 = 4 + 5

0

0

1

1

2

3

3

6

reduce((x,y)=>x+y,0)

Page 34: Arquitecturas Reactivas para Front End

@javiervelezreye34

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

C.EncadenamientodeOperadores

II.FrameworkSencillodeProgramaciónReac:va

Nuestrosoperadoresaplican funcionesde transformaciónydevuelvenel resultadodedichaaplicación. Como tal no pueden encadenarse de acuerdo a una sintaxis de API fluida. Esnecesariodefinirunafunciónqueadaptecadafunciónadecuadamenteenestesen2do.

var numbers = fromValues([2,3,4]) .map(sqr) .filter(even) .scan(add, 0) .end(); numbers(console.log); sqr

even

add

function fluent (hn) { var cb = hn || function () {}; return function (fn) { return function () { cb(fn.apply(this, arguments)); return this; }; }; }

Se pretende transformar de forma transparentelas funcionesmap, filter y scan para que puedanserencadenadasennotacióndepuntoamododeAPIfluida

El ordenenque se incluyen lastransformaciones sqr, even yadd en la expresión de APIfluida corresponde al orden enque éstas son añadidas en lacadenareacCva

Necesitamos transformar los operadores a través de lafunción fluid que genera una función para ejecutar eloperador,entregarelresultadoaunmanejadorydevolverunareferenciaalobjetodecontextosobreelqueseaplicael operador punto para poder seguir encadenandooperadores

Page 35: Arquitecturas Reactivas para Front End

@javiervelezreye35

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

D.ComposicióndeTransformaciones

II.FrameworkSencillodeProgramaciónReac:va

Unavezlogradoelobje2vodeencadenaroperadoresyantesdecerrarnuestroframeworkesnecesariodefinirunafuncióndesecuenciamientoqueapliquecomposi2vamentecadafuncióndetransformacióndentrodelacadena.Veamoscomohacerlo.

function sequence (fns) { return function (x) { return fns.reduce (function (ac, fn) { return (ac !== void 0) ? fn(ac) : void 0; }, x); }; }

Lafunciónsequencerecorreelarraydefuncionespasado como parámetro y lo aplica composiCva-mente a parCr del parámetro x. Como se ve laimplementación hace uso de una estrategia dereducción conbase en x y garanCzaque en todomomento cada función aplicada devuelve unresultadononulo

var s = sequence([ map(sqr), filter(even), scan(add, 0) ]); s(3) // undefined (even(9) === false) S(2) // 4

Para entendermejor como opera esta función pensemosenunejemploconelarrayde funciones [sqr,even,add].Pretendemosconstruirunafunciónquecuandoseinvoquesobre x devuelva el resultado composiCvo equivalente aevaluarlaexpresiónadd(even(sqr(x)))

Page 36: Arquitecturas Reactivas para Front End

@javiervelezreye36

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

E.ConstructorStream

II.FrameworkSencillodeProgramaciónReac:va

Despuésdetodoestetrabajosólorestadefinirel constructor Stream que proporciona elobjetodecontextodondesedefinirálacadenade composición, incluir las funciones anterio-resyañadiralgunalógicaadicionalparasopor-tarelprocesoderegistrodeescuchadores.

PatrónStreamPush

function Stream (source) { var fns = []; var lns = []; var define = fluent (function (fn) { fns.push (fn); }); return { map : define (map), filter: define (filter), scan : define (scan), end: function () { var seq = sequence(fns); source(function (data) { var result = seq(data); lns.forEach(function (ln) { if (result) ln (result); }); }); return { listen: function (ln) { lns.push(ln); } }; } }; }

La colección lns acumula los escuchadores que seregistran al stream para ser noCficados de cadanuevoresultadoprocesadoLafunciónendaplicasequenceunavezparaobtenerla cadena de composición y después arranca lafuente con un manejador que obCene el siguienteresultado y si es definido lo publica a cadaescuchadorComoretornosedevuelveunobjetoconunmétodolisten que permite registrar nuevos manejadoresasociadosaescuchadoresinteresados

Page 37: Arquitecturas Reactivas para Front End

@javiervelezreye37

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

Antesdeterminarrepasaremosunpardeejemplossencillosquepuedenserdesarrolladosconnuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectoscompara2voslaversióntradicionalbasadaeneventosWebparaapreciarsusdiferencias.

III.Evaluación

var data = serie (function (x) { return x + 1; }, 0); var source = fromSerie(data); var stream = Stream (source) .map (function (e) { return e * e; }) .filter (function (e) { return e % 2 === 0}) .scan (function (a, e) { return a + e; }, 0) .end (); stream.listen (console.log);

Laseriededatosgenerauniteradordenaturales que se emplea como fuentepush para una cadena de trasforma-dores [sqr,event,add].Trasfinalizar ladeclaración de la cadena, se invoca elmétodo listen para registrar a laconsolacomoúnicoescuchador

SumadeCuadradosPares

var idx = 0; var sqr = function (n) { var sqrn = n * n; if (sqrn % 2 === 0) console.log (sqrn); idx++; setTimeout(function () { sqr(n+1); }, 1000); }; sqr(0);

La versión imperaCva de este problema esconsiderablemente menos declaraCva que laformareacCva.Ademássetratadeunasoluciónconestadodondeelestadonoestáencapsuladosinomantenidoporunavariableexternaidx.

Reac:vo

Clásico

Page 38: Arquitecturas Reactivas para Front End

@javiervelezreye38

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

Antesdeterminarrepasaremosunpardeejemplossencillosquepuedenserdesarrolladosconnuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectoscompara2voslaversióntradicionalbasadaeneventosWebparaapreciarsusdiferencias.

III.Evaluación

En el enfoque clásico se uClizanvariables para referir los elementos(display & btns) y para mantener elestado (count) así comoestructurasdecontroldeflujoparaarCcularelprocesoderegistrodeescuchadores

ContadordeClicks

<button id="up" class="btn">Up</button> <button id="down" class="btn">Down</button> <span id="display"></span> <script> var count = 0; var display = document.querySelector('#display'); var btns = document.querySelectorAll('.btn'); var register = function (idx) { btns[idx].addEventListener ('click', function (e) { if (e.currentTarget.id === 'up') count++; if (e.currentTarget.id === 'down') count--; display.innerHTML = count; }); }; for (var idx=0; idx < btns.length; idx++) register(idx); </script>

Clásico

Up Down 7

Page 39: Arquitecturas Reactivas para Front End

@javiervelezreye39

UnFrameworkSencillodeProgramaciónReac2vaArquitecturasReac:vasdeStreams

Antesdeterminarrepasaremosunpardeejemplossencillosquepuedenserdesarrolladosconnuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectoscompara2voslaversióntradicionalbasadaeneventosWebparaapreciarsusdiferencias.

III.Evaluación

LaversiónreacCvaresultamuchomásdeclaraCvaylimpia.Primero se crea una fuente adaptadora de eventos clicksobre el target .btn y después se define una cadenaformadapordosoperaciones, laprimera idenCficaelpasode incrementoquesedebeaplicara lasumay lasegundarealizalasuma.Aquínoexistecontadorexplícito

ContadordeClicks

var source = fromTargetAll('.btn', 'click'); var stream = Stream (source) .map (function (e) { return e.currentTarget.id === 'up' ? 1 : -1 }) .scan (function (a, e) { return a + e; }, 0) .end (); stream.listen (function (n) { document.querySelector('#display').innerHTML = n; });

Reac:vo

Up Down 7

Page 40: Arquitecturas Reactivas para Front End

@javiervelezreye40

PreguntasArquitecturasReac:vasdeStreams

Eventos

StreamComposiciónReac:vidad

JavierVélezReyes@javiervelezreye

[email protected]

Page 41: Arquitecturas Reactivas para Front End

JavierVélezReyes@javiervelezreye

[email protected]

ArquitecturasReac-vasdeStreams

ArquitecturasdeFrontend

Octubre2014