Rxjs 101

@HenarMendiola

who am i?

  • Doctora en Física de sistemas complejos
  • Desarrolladora en eldiario.es

Comunidades

@HenarMendiola

Índice

  • Programación reactiva: por qué y para qué
  • Conceptos básicos
  • Con las manos en la masa
  • Un gran poder conlleva una gran responsabilidad
  • Conclusiones

@HenarMendiola

PR

Conceptos básicos

Con las manos en la masa

 

Gran poder

Fin

@HenarMendiola

PR

Conceptos básicos

Con las manos en la masa

 

Gran poder

Fin

@HenarMendiola

¿Programación reactiva?

  • Propagación del cambio

 

  • Flujos de datos asíncronos

@HenarMendiola

¿Programación reactiva?

  • Responsivos
  • Resilientes
  • Elásticos
  • Orientados a mensajes

@HenarMendiola

Responsivos

@HenarMendiola

Resilientes

@HenarMendiola

@HenarMendiola

Elásticos

@HenarMendiola

Orientados a mensajes

¿Programación reactiva?

  • Pensado para dar solución:
    • Problemas de capacidad
    • Interrupciones en la red
    • Problemas de hardware
    • Errores

¿Programación reactiva?

  • Beneficios:
    • Escalabilidad
    • Ahorro

Conceptos básicos

Observable

@HenarMendiola

Observable

  • Valores futuros
  • Valores "lazy" y "push"
  • Hay que estar suscrito sí o sí para invocar la ejecución
  • Proveen valores múltiples a lo largo del tempo

@HenarMendiola

Observable

const { interval } = require('rxjs');

const myFirstObservable = interval(500);

@HenarMendiola

Subscripción

@HenarMendiola

Subscripción

  • Ejecución de un observable
  • Se usa para cancelar la ejecución
  • Si no hay subscripción, jamás se ejecuta el flujo

@HenarMendiola

Subscripción

const { interval } = require('rxjs');

const myFirstObservable = interval(500);

myFirstObservable.subscribe();

@HenarMendiola

Observador

@HenarMendiola

Observador

  • La función última por la que pasan los observables
  • Conjunto de callbacks
  • Se provee dentro de la subscripción del observable

@HenarMendiola

Observador

const { interval } = require('rxjs');

const myFirstObservable$ = interval(500);

const myObserver = {
  next: (x) => console.log('next ', x),
  complete: () => console.log('complete'),
  error: (e) => console.log('error ', e),
}

myFirstObservable$.subscribe(myObserver);

@HenarMendiola

Obserbador

next  0
next  1
next  2
next  3
next  4
next  5
next  6
next  7
next  8
next  9

@HenarMendiola

Operadores

@HenarMendiola

Operadores

  • Funciones que nos permiten componer el flujo de forma declarativa
  • No modifica el observable original
  • Devuelve un nuevo observable

@HenarMendiola

Operadores

  • Algunos tipos:
    • Creación
    • Unión
    • Transformación
    • Filtrado
    • Utilidades
    • Matemáticos...

@HenarMendiola

Operadores

const {
  map,
  interval,
  filter,
  take
} = require('rxjs');

const myFirstObservable$ = interval(500);

const myObserver = {
  next: (x) => console.log('next ', x),
  complete: () => console.log('complete'),
  error: (e) => console.log('error ', e),
}

myFirstObservable$
  .pipe(
    filter(x => x%2 === 0),
    map(x => x + 5),
    take(5)
  )
  .subscribe(myObserver);

@HenarMendiola

Operadores

next  5
next  7
next  9
next  11
next  13
complete

@HenarMendiola

Con las manos en la masa

@HenarMendiola

Un gran poder...

@HenarMendiola

Evitar lógica dentro de subscribe

@HenarMendiola

const {  interval } = require('rxjs');
const observable$ = interval(700);

observable$
  .subscribe((value) => {
    const triple = value * 3;
    if ( triple % 2 !== 0) {
      return
    } else {
      console.log('mi number ', triple);
    }
  })

@HenarMendiola

const {
  interval,
  filter,
  map,
  tap
} = require('rxjs');

const observable$ = interval(700);

observable$
  .pipe(
    map(x => x * 3),
    filter(x => x % 2 === 0),
    tap(console.log)
  )
  .subscribe()

@HenarMendiola

Evitar la lógica duplicada

@HenarMendiola

const kitten = [
  {
    name: 'Assata',
    nickname: 'Croquetis',
    age: 1,
    colors: ['black', 'white'],
    hunger: 20,
    weight: 3,
    state: 'alive'
  },   {
    name: 'Txomski',
    nickname: 'Pistachete',
    age: 8,
    hunger: 10,
    weight: 4,
    colors: ['black'],
    state: 'alive'
  },  {
    name: 'Misis',
    nickname: 'La señora',
    age: 12,
    hunger: 20,
    weight: 3,
    colors: ['brown', 'black', 'white'],
    state: 'dead'
  },
];

@HenarMendiola

const kitten$ = from(kitten);

kitten$
  .pipe(
    filter(cat => cat.state !== 'dead'),
    scan((acum, curr) => {
      return acum + curr.age;
    }, 0)
  )
  .subscribe(
    (x) => console.log('total age ', x)
  )

  kitten$
  .pipe(
    filter(cat => cat.state !== 'dead'),
    scan((acum, curr) => {
      return acum + curr.weight * curr.hunger;
    }, 0)
  )
  .subscribe(
    (x) => console.log('total hunger ', x)
    )

@HenarMendiola

Evitar la lógica duplicada

const aliveKittens$ = from(kitten)
  .pipe(
    filter(cat => cat.state !== 'dead')
    );

aliveKittens$
  .pipe(
    scan((acum, curr) => {
      return acum + curr.age
    }, 0)
  )
  .subscribe(
    (x) => console.log('total age ', x)
  );

  aliveKittens$
  .pipe(
    scan((acum, curr) => {
      return acum + curr.weight * curr.hunger;
    }, 0)
  )
  .subscribe(
    (x) => console.log('total hunger ', x)
    );

@HenarMendiola

Utilizar share para streams duplicado

const {
  share,
  map,
  tap,
  fromEvent,
  switchMap
} = rxjs;

const { fromFetch } = rxjs.fetch;

const options = {
  method: 'GET',
  url,
  headers,
  selector: res => res.json()
};

const fetch$ = 
  fromFetch(
    url,
    options
  )

fetch$.subscribe(console.log);
fetch$.subscribe(console.log);
const {
  share,
  map,
  tap,
  fromEvent,
  switchMap
} = rxjs;

const { fromFetch } = rxjs.fetch;

const options = {
  method: 'GET',
  url,
  headers,
  selector: res => res.json()
};

const fetch$ = 
  fromFetch(
    url,
    options
  ).pipe(share())

fetch$.subscribe(console.log);
fetch$.subscribe(console.log);

Evitar anidamiento

Evitar anidamiento

Utilizar subject para finalizar las subscripciones

Utilizar subject para finalizar las subscripciones

Conclusiones

@HenarMendiola

  • Hemos destripado observables, suscripciones y observadores con el fin de entenderlos mejor

@HenarMendiola

  • Hemos destripado observables, susbcripciones y observadores con el fin de entenderlos mejor

 

  • Para trabajar con observables es necesario suscribirnos

@HenarMendiola

  • Hemos destripado observables, susbcripciones y observadores con el fin de entenderlos mejor

 

  • Para trabajar con observables es necesario suscribirnos

 

  • La programación reactiva nos provee de herramientas para hacer un código principalmente declarativo

@HenarMendiola

  • La programación reactiva es una forma de programación que optimiza recursos

@HenarMendiola

  • La programación reactiva es una forma de programación que optimiza recursos


  • La eficiencia de la programación reactiva depende del buen uso de la misma

@HenarMendiola

Bibliografía

@HenarMendiola

  • Documentación rxjs: https://rxjs.dev/guide/overview

 

  • Programación reactiva: características y aplicaciones: https://www.doonamis.es/que-es-la-programacion-reactiva/

 

  • Aprende rxjs desde cero: http://blog.enriqueoriol.com/2019/04/aprende-rxjs-3.html

@HenarMendiola

  • Learning Observable by building observable: https://benlesh.medium.com/learning-observable-by-building-observable-d5da57405d87

 

  • Rxjs from scratch: https://dev.to/mr_bertoli/rxjs-from-scratch-observables-hl6

 

  • Proyectos rxjs: https://www.learnrxjs.io/learn-rxjs/recipes/

@HenarMendiola

  • El manifisto de los sistemas reactivos: https://www.reactivemanifesto.org/es

 

 

@HenarMendiola

@HenarMendiola

deck

By Henar Hernandez

deck

  • 83