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.
2. @javiervelezreye 2
Presentación
Arquitecturas Reac:vas de Streams
Licenciado en informá2ca por la Universidad Politécnica de
Madrid (UPM) desde el año 2001 y doctor en informá2ca por la
Universidad Nacional de Educación a Distancia (UNED) desde el
año 2009, Javier es inves2gador y está especializado en el diseño
y análisis de la colaboración. Esta labor la compagina con
ac2vidades de evangelización, consultoría, mentoring y formación
especializada para empresas dentro del sector IT. Inquieto, ávido
lector y seguidor cercano de las innovaciones en tecnología.
I. ¿Quién Soy?
II. ¿A Qué Me Dedico?
Desarrollado Front/Back
Evangelización Web
Arquitectura SoVware
Formación & Consultoría IT
E-learning
Diseño de Sistemas de Colaboración
Learning Analy2cs
Gamificación Colabora2va
javier.velez.reyes@gmail.com
@javiervelezreye
linkedin.com/in/javiervelezreyes
gplus.to/javiervelezreyes
jvelez77
javiervelezreyes
youtube.com/user/javiervelezreyes
5. @javiervelezreye 5
Introducción
Arquitecturas Reac:vas de Streams
B. Arquitecturas Centradas en el Modelo
I. El Camino Hacia las Arquitecturas Reac:vas
Como evolución del modelo de construcción basado en programación de escuchadores,
emergieron una serie de arquitecturas que se recogen bajo el acrónico MV* por sus similitudes
entre sí. Todas ellas comparten la premisa de que están centradas en un modelo interno cuyos
cambios son atendidos por la vista a través de cierta lógica de control. En general este
paraguas recoge diversas variantes arquitectónicas.
Modelo
Vista Controlador
Usuario
manipula
actualiza
MVC
observa usa
Modelo
Adapter
Usuario
manipula
actualiza
MVA
observa usa
Model View Controller
El controlador manipula la vista en
respuesta a las interacciones del
usuario y el modelo actualiza la vista
Model View Adapter
El modelo no se comunica con la vista.
Es el adaptador el encargado de
propagar los cambios en ambas partes
Vista
6. @javiervelezreye 6
Introducción
Arquitecturas Reac:vas de Streams
B. Arquitecturas Centradas en el Modelo
I. El Camino Hacia las Arquitecturas Reac:vas
Como evolución del modelo de construcción basado en programación de escuchadores,
emergieron una serie de arquitecturas que se recogen bajo el acrónico MV* por sus similitudes
entre sí. Todas ellas comparten la premisa de que están centradas en un modelo interno cuyos
cambios son atendidos por la vista a través de cierta lógica de control. En general este
paraguas recoge diversas variantes arquitectónicas.
M
V C
HMVC
Modelo
Presenter
Usuario
manipula
actualiza
MVP
observa usa
Model View Controller Jerárquico
Los modelos MVC se distribuyen entre el
aplicaCvo para cada componente que se
organizan agregaCvamente
Model ViewPresenter
Como extensión del MVA, el patrón MVP hace
que el controlador se mantenga a las escucha
de los cambios en la vista y el modelo
M
V C
M
V C
Vista
7. @javiervelezreye 7
Introducción
Arquitecturas Reac:vas de Streams
B. Arquitecturas Centradas en el Modelo
I. El Camino Hacia las Arquitecturas Reac:vas
Como evolución del modelo de construcción basado en programación de escuchadores,
emergieron una serie de arquitecturas que se recogen bajo el acrónico MV* por sus similitudes
entre sí. Todas ellas comparten la premisa de que están centradas en un modelo interno cuyos
cambios son atendidos por la vista a través de cierta lógica de control. En general este
paraguas recoge diversas variantes arquitectónicas.
Model View View-Model
La vista y el modelo de vista permanecen
sincronizados a través de una arquitectura
de observadores y mutadores
Vista Modelo de Vista
Usuario
MVVM
Observa &
interacciona
Data
binding
Modelo
actualiza
9. @javiervelezreye 9
Introducción
Arquitecturas Reac:vas de Streams
A. Dirigida por los Datos
II. Principios de Programación Reac:va
Las arquitecturas de programación funcional reac2va definen cadenas de transformación
funcional que son atravesadas por flujos de datos para su procesamiento. Se dice que este 2po
de soluciones está dirigida por los datos por que en ellos descansa gran parte de la lógica de la
aplicación y el propio comportamiento reac2vo del sistema.
Click
click, click, click...
filter
group
take(10)
f
Cadena de Transformación
La cadena de transformación filtra los eventos
de usuario, los agrupa por pares si éstos se
producen con cierta frecuencia temporal para
representar el doble click y finalmente absorbe
sólo los 10 primeros
Comportamiento dirigido por datos
La naturaleza de los datos atravesados
por la cadena de transformación
condiciona cuándo se ejecutará f
15. @javiervelezreye 15
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
La programación funcional reac2va es un modelo de programación que pretende dar respuesta
a la demanda creciente de nuevos sistemas más flexibles, elás2cos y tolerantes a fallos a par2r
de los principios propios de la programación funcional. Esta aproximación resulta muy
ventajosa en tanto que produce desarrollos más declara2vos y explícitos centrados en las
transformaciones que deben sufrir los datos para su procesamiento.
I. Arquitecturas Web Reac:vas
Las Arquitectura Web Reac-vas son sistemas soaware que
operan en reacción a los eventos ocurridos sobre el modelo de
datos DOM de la Web. Cada evento atraviesa una cadena de
transformación funcional para su procesamiento.
La lógica de negocio de una arquitectura
reacCva queda capturada en la cadena de
transformaciones que es atravesada por cada
evento. Estas transformaciones son en general
inmutables, idempotentes y agnósCcas de las
condiciones ambientales
I. Construcción Composi:va
Paradójicamente, las operaciones de
transformación que arCculan las arquitec-
turas reacCvas están en estrecha relación
con el Cempo ya que éste es un factor
determinante a la hora de construir modelos
de comportamiento reacCvo
II. Modelado Explicito del Tiempo
16. @javiervelezreye 16
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
Desde un punto de vista estructural, las arquitecturas de programación funcional reac2va
están caracterizadas por una colección de abstracciones funcionales. Estas abstracciones se
encadenan secuencialmente para que lleven a cabo las tareas de procesamiento y
transformación de eventos desde la fuente emisora a los sumideros receptores de manera que
toda la lógica de negocio se expresa de forma declara2va y distribuida a lo largo de la cadena.
II. Visión Está:ca
Fuente
La fuente es la encargada de
proporcionar los eventos a la
cadena de transformación
Cadena de Transformación
Las operaciones de transfor-
mación funcional se enca-
denan composiCvamente
Sumidero
Al final de cada cadena se pueden
colocar receptores que recogen los
datos procesados e incluso pueden
mezclarse con otras cadenas
Transformación
Cada operación dentro de la cadena
es una transformación funcional no
mutadora
Stream de Eventos
Los eventos provenientes de la
fuente de datos fluyen discrecional-
mente a lo largo del Cempo
18. @javiervelezreye 18
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
B. Diagramas de Reac:vidad
III. Visión Dinámica
La mejor manera de razonar sobre las arquitectura reac2vas es por medio del uso de
diagramas de reac2vidad. Un diagrama de reac2vidad es una representación alterna de líneas
de 2empo y operaciones de transformación funcional. Cada una de estas operaciones recibe
como entrada la línea de 2empo anterior y genera como salida la línea subsiguiente.
clicks
groups
size 3 2 1
Double click 3 2
Cada operación recibe
una línea de Cempo
como entrada y genera a
su salída otra línea de
Cempo con eventos
nuevos
Operaciones
Cada línea es una proyección a
lo largo del Cempo de lo que
ocurre en el sistema en un
punto determinado de la
cadena
Líneas de Tiempo
buffer (throdle (250 ms))
map (get length of group)
filter (size > 1)
19. @javiervelezreye 19
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
B. Diagramas de Reac:vidad
III. Visión Dinámica
Los diagramas de reac2vidad ofrecen una visión del comportamiento de las arquitecturas
reac2vas en torno a dos perspec2vas ortogonales. En cada ver2cal se puede comprobar cuál es
el proceso de transformación que sufre un evento en un momento del 2empo.
Horizontalmente, se contempla el comportamiento de cada fase a lo largo del 2empo
clicks
groups
size
Double click
Se razona sobre lo que
ocurre en un instante de
Cempo con el procesa-
miento de un evento
concreto a lo largo de la
cadena
Dimensión Ver:cal
Se razona acerca de cómo se
comporta cada fase y el
proceso independientemente
de la dimensión Cempo
Dimensión Horizontal
3 2 1
3 2
buffer (throdle (250 ms))
map (get length of group)
filter (size > 1)
20. @javiervelezreye 20
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
C. Operaciones Reac:vas
III. Visión Dinámica
Para completar la descripción del comportamiento dinámico es necesario conocer las
principales operaciones que pueden aplicarse para definir cadenas de transformación. El léxico
de las mismas cambia de una librería a otra pero en esencia todas proporcionan el mismo
juego de facilidades declara2vas.
Operaciones de Creación
Las operaciones de creación permiten crear
disCntas fuentes de eventos en relación a
disCntos orígenes asíncronos de datos
subscribe ( f )
Operaciones de Terminación
Las operaciones de terminación permiten
definir sumideros al final de una cadena
reacCva
stream ( css )
values ( interval, v )
serie ( delay, it)
error ( f )
end ( f )
21. @javiervelezreye 21
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
C. Operaciones Reac:vas
III. Visión Dinámica
Para completar la descripción del comportamiento dinámico es necesario conocer las
principales operaciones que pueden aplicarse para definir cadenas de transformación. El léxico
de las mismas cambia de una librería a otra pero en esencia todas proporcionan el mismo
juego de facilidades declara2vas.
Operaciones de Mezcla de Streams
Las operaciones de entrelazado y mezcla de streams de eventos permiten fusionar
varios streams de eventos para crear streams de eventos compuestos. Esto permite
que un mismo stream pueda ser procesado por más de una cadena de composición
de forma simultanea
concat
4 1
5 3 2 7 6
5 4 1 7 6
merge
4 1
5 3 2
3 2 1 5 4
startWith (v)
v
4 3 2
3 2 v 5 4
5
22. @javiervelezreye 22
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
C. Operaciones Reac:vas
III. Visión Dinámica
Del capítulo anterior ya ha quedado patente que las arquitecturas reac2vas presentan una
clara formulación funcional. Se trata en esencia de definir cadenas de transformación que
serán atravesadas por los datos según van generándose. Sin embargo en términos más
prác2cos existen una serie de carácterís2cas diferenciales que resumimos a con2nuación.
Operaciones de Ges:ón Temporal
Las operaciones de gesCón del Cempo permiten modelar
comportamientos reacCvos que Cenen en cuenta condiciones temporales
en relación a los eventos. Dado que estas funciones dependen de las
condiciones ambientales y frecuentemente no Cenen un comportamiento
idempotente su ajuste al paradigma funcional queda un poco en
entredicho.
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 ( 10 ms )
throdle ( 5 ms )
23. @javiervelezreye 23
Conceptos Esenciales
Arquitecturas Reac:vas de Streams
C. Operaciones Reac:vas
III. Visión Dinámica
Del capítulo anterior ya ha quedado patente que las arquitecturas reac2vas presentan una
clara formulación funcional. Se trata en esencia de definir cadenas de transformación que
serán atravesadas por los datos según van generándose. Sin embargo en términos más
prác2cos existen una serie de carácterís2cas diferenciales que resumimos a con2nuación.
Operaciones de Secuenciamiento
Las operaciones clásicas de secuenciamiento
(map, reduce, filter) se adaptan al modelo
unitario de procesamiento reacCvo
map ( f ) filter ( f )
3
3
4
7
scan ( 0, + )
Operaciones de Asincronía
Las operaciones asíncronas permiten
gesConar disCntos aspectos relacionados
con el carácter asíncrono de los eventos
3 4
7
reduce ( 0, + )
map ( p )
p
v
p
v
flatMap ( p )
25. @javiervelezreye 25
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
A. Modelos de Operación Pull & Push
I. Modelos de Programación Reac:va
Es posible caracterizar las arquitecturas de programación funcional reac2va en virtud de la
naturaleza síncrona o asíncrona de los datos que procesan. Ello da lugar a sendos modelos de
operación conocidos con el nombre de Pull y Push respec2vamente. En el primer caso, es el
sumidero el que pide nuevos datos a la cadena mientas que en el segundo es la fuente la
encargada de empujar dichos datos proac2vamente en cuanto éstos son generados.
I. Modelo Pull
En el modelo pull, el sumidero solicita nuevos
datos y la solicitud recorre ascendentemente la
cadena hasta llegar a la fuente
La fuente es la enCdad pasiva
que genera nuevos datos bajo
demanda
I. Modelo Push
En el modelo push, a medida que se disponen de
nuevos datos, la fuente los empuja por la cadena
de transformación hacia abajo
La fuente es la enCdad acCva
que produce datos y los
entrega a la cadena
El sumidero es la enCdad
acCva que pide a la cadena
nuevos datos procesados para
ser consumidos
El sumidero es una enCdad
pasiva que se manCene a la
escucha para consumir datos
cuando llegan desde la cadena
27. @javiervelezreye 27
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
C. Clasificación
I. Modelos de Programación Reac:va
Es posible establecer las dos caracterizaciones anteriores como dos ejes dimensionales
dispuestos ortogonalmente. Ello da lugar a un espacio de clasificación que divide las
arquitecturas reac2vas en cuatro familias. Nosotros centraremos nuestra atención en
arquitecturas Web reac2vas.
Modelos Con:nuos
Basados en Streams
Modelos Discretos
Basados en Eventos
Modelos Síncronos
Modo Pull
Modelos Asíncronos
Modo Push
Programación Web Reac:va
BigData Event Processing
Modelo de Actores
WebSockets
Iteradores & Generadores
Colecciones Infinitas
Evaluación Perezosa
Signal Processing
Noise Generators
Streamming de datos
Video & Audio Streams
Web Audio API
WebRTC
28. @javiervelezreye 28
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
A. Generación de Fuentes
II. Framework Sencillo de Programación Reac:va
Como hemos visto en el capítulo anterior existe una gran variedad de constructores que
permiten definir fuentes asíncronas que funcionan en modo Push. Aquí nos centraremos en
presentar el código interno de las más comúnmente u2lizadas.
Adaptador de Evento Web
Los adaptadores de eventos son funciones
que recogen eventos Web y los redirigen a
una función manejadora pasada como
argumento en una segunda fase de
evaluación
En este ejemplo se ve cómo la función
fromTarget construye una fuente s a parCr
de un selector css y un Cpo de evento
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>
29. @javiervelezreye 29
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
A. Generación de Fuentes
II. Framework Sencillo de Programación Reac:va
Como hemos visto en el capítulo anterior existe una gran variedad de constructores que
permiten definir fuentes asíncronas que funcionan en modo Push. Aquí nos centraremos en
presentar el código interno de las más comúnmente u2lizadas.
Adaptador de Colección
Los adaptadores de colección persiguen
generar fuentes push que iteran circular-
mente sobre los elementos de una colección
a intervalos regulares de Cempo
La función fromValues recibe un array de
valores y un intervalo de Cempo y construye
una función que emiCrá un evento con el
valor siguiente en la colección cada vez que
es invocado
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 la
fuente asíncrona de eventos emite circularmente, a
intervalos regulares de 1 segundo, los elementos
del array pasado como parámetro de entrada. Los
eventos se vinculan al escuchador de salida
estándar
30. @javiervelezreye 30
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
A. Generación de Fuentes
II. Framework Sencillo de Programación Reac:va
Como hemos visto en el capítulo anterior existe una gran variedad de constructores que
permiten definir fuentes asíncronas que funcionan en modo Push. Aquí nos centraremos en
presentar el código interno de las más comúnmente u2lizadas.
Adaptador de Iteración
La función serie toma una función genérica fn y
devuelve otra función iteradora que genera valores
consecuCvos aplicando dicha función
fromSerie es una fuente push que invoca la serie
pasada como parámetro a intervalos regulares de
Cempo. Esta es una manera de hacer un adaptador
Push sobre una fuente Pull
El código de ejemplo define la función inc y sobre ella
genera la serie de números naturales num. Despues
construye una fuente y la vincula a la salida está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);
34. @javiervelezreye 34
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
C. Encadenamiento de Operadores
II. Framework Sencillo de Programación Reac:va
Nuestros operadores aplican funciones de transformación y devuelven el resultado de dicha
aplicación. Como tal no pueden encadenarse de acuerdo a una sintaxis de API fluida. Es
necesario definir una función que adapte cada función adecuadamente en este sen2do.
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 transparente
las funciones map, filter y scan para que puedan
ser encadenadas en notación de punto a modo de
API fluida
El orden en que se incluyen las
transformaciones sqr, even y
add en la expresión de API
fluida corresponde al orden en
que éstas son añadidas en la
cadena reacCva
Necesitamos transformar los operadores a través de la
función fluid que genera una función para ejecutar el
operador, entregar el resultado a un manejador y devolver
una referencia al objeto de contexto sobre el que se aplica
el operador punto para poder seguir encadenando
operadores
36. @javiervelezreye 36
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
E. Constructor Stream
II. Framework Sencillo de Programación Reac:va
Después de todo este trabajo sólo resta definir
el constructor Stream que proporciona el
objeto de contexto donde se definirá la cadena
de composición, incluir las funciones anterio-
res y añadir alguna lógica adicional para sopor-
tar el proceso de registro de escuchadores.
Patrón Stream Push
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 se
registran al stream para ser noCficados de cada
nuevo resultado procesado
La función end aplica sequence una vez para obtener
la cadena de composición y después arranca la
fuente con un manejador que obCene el siguiente
resultado y si es definido lo publica a cada
escuchador
Como retorno se devuelve un objeto con un método
listen que permite registrar nuevos manejadores
asociados a escuchadores interesados
37. @javiervelezreye 37
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
Antes de terminar repasaremos un par de ejemplos sencillos que pueden ser desarrollados con
nuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectos
compara2vos la versión tradicional basada en eventos Web para apreciar sus diferencias.
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);
La serie de datos genera un iterador de
naturales que se emplea como fuente
push para una cadena de trasforma-
dores [sqr, event, add]. Tras finalizar la
declaración de la cadena, se invoca el
método listen para registrar a la
consola como único escuchador
Suma de Cuadrados Pares
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 es
considerablemente menos declaraCva que la
forma reacCva. Además se trata de una solución
con estado donde el estado no está encapsulado
sino mantenido por una variable externa idx.
Reac:vo
Clásico
38. @javiervelezreye 38
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
Antes de terminar repasaremos un par de ejemplos sencillos que pueden ser desarrollados con
nuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectos
compara2vos la versión tradicional basada en eventos Web para apreciar sus diferencias.
III. Evaluación
En el enfoque clásico se uClizan
variables para referir los elementos
(display & btns) y para mantener el
estado (count) así como estructuras de
control de flujo para arCcular el proceso
de registro de escuchadores
Contador de Clicks
<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
39. @javiervelezreye 39
Un Framework Sencillo de Programación Reac2va
Arquitecturas Reac:vas de Streams
Antes de terminar repasaremos un par de ejemplos sencillos que pueden ser desarrollados con
nuestro framework de forma declara2va. Para cada ejemplo incluiremos a efectos
compara2vos la versión tradicional basada en eventos Web para apreciar sus diferencias.
III. Evaluación
La versión reacCva resulta mucho más declaraCva y limpia.
Primero se crea una fuente adaptadora de eventos click
sobre el target .btn y después se define una cadena
formada por dos operaciones, la primera idenCfica el paso
de incremento que se debe aplicar a la suma y la segunda
realiza la suma. Aquí no existe contador explícito
Contador de Clicks
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