ReactiveX ( Rx , también conocido como Reactive Extensions ) es una biblioteca de software creada originalmente por Microsoft que permite a los lenguajes de programación imperativos operar con secuencias de datos, independientemente de si estos son síncronos o asíncronos . Proporciona un conjunto de operadores de secuencia que actúan sobre cada elemento de la secuencia. Es una implementación de la programación reactiva y ofrece un modelo para la implementación de herramientas en múltiples lenguajes de programación .
Descripción general
ReactiveX es una API para programación asíncrona con flujos observables. [ 1 ]
La programación asíncrona permite a los programadores llamar a funciones y que estas, al finalizar, realicen una devolución de llamada, generalmente proporcionándoles la dirección de otra función que se ejecutará una vez terminada. Los programas diseñados de esta manera suelen evitar la sobrecarga que supone tener muchos hilos de ejecución que se inician y se detienen constantemente.
En el contexto de Reactive Extensions, los flujos observables (es decir, los flujos que se pueden observar) funcionan como emisores de eventos que emiten tres eventos: next, error y complete. Un observable emite eventos next hasta que emite un evento error o un evento complete. Sin embargo, a partir de ese momento, no emitirá más eventos, a menos que se vuelva a suscribir.
Los ejemplos que se muestran a continuación utilizan la implementación RxJS de Reactive Extensions para el lenguaje de programación JavaScript.
Motivación
Para secuencias de datos, combina las ventajas de los iteradores con la flexibilidad de la programación asíncrona basada en eventos. Además, funciona como una promesa simple, eliminando la compleja estructura que resulta de múltiples capas de funciones de devolución de llamada.
Observables y observadores
ReactiveX es una combinación de ideas de los patrones observador e iterador y de la programación funcional . [ 2 ]
Un observador se suscribe a una secuencia observable. La secuencia envía los elementos al observador uno a uno, generalmente mediante la llamada a la función de devolución de llamada proporcionada. El observador procesa cada elemento antes de procesar el siguiente. Si llegan muchos eventos de forma asíncrona, deben almacenarse en una cola o descartarse. En ReactiveX, un observador nunca recibirá una llamada con un elemento fuera de orden ni (en un contexto multihilo) antes de que la función de devolución de llamada haya finalizado para el elemento anterior. Las llamadas asíncronas siguen siendo asíncronas y pueden gestionarse devolviendo un observable.
Es similar al patrón de iteradores, ya que si ocurre un error fatal, notifica al observador por separado (llamando a una segunda función). Cuando se han enviado todos los elementos, finaliza (y notifica al observador llamando a una tercera función). La API de Reactive Extensions también toma prestados muchos de sus operadores de los operadores de iteradores de otros lenguajes de programación.
Reactive Extensions es diferente de la programación reactiva funcional , como se explica en la Introducción a Reactive Extensions:
A veces se le llama "programación reactiva funcional", pero este término es inapropiado. ReactiveX puede ser funcional y reactivo, pero la "programación reactiva funcional" es algo distinto. Una diferencia fundamental radica en que la programación reactiva funcional opera sobre valores que cambian continuamente con el tiempo, mientras que ReactiveX opera sobre valores discretos que se emiten a lo largo del tiempo. (Para obtener información más precisa sobre la programación reactiva funcional, consulte el trabajo de Conal Elliott). [ 2 ]
Operadores reactivos
Un operador es una función que toma un observable (el origen) como primer argumento y devuelve otro observable (el destino u observable externo). Luego, por cada elemento que emite el observable de origen, aplica una función a dicho elemento y lo emite en el observable de destino. Incluso puede emitir otro observable en el observable de destino. Esto se denomina observable interno.
Un operador que emite observables internos puede ser seguido por otro operador que de alguna manera combina los elementos emitidos por todos los observables internos y emite el elemento en su observable externo. Algunos ejemplos son:
switchAll– se suscribe a cada nuevo observable interno tan pronto como se emite y se da de baja del anterior.mergeAll– Se suscribe a todas las observables internas a medida que se emiten y produce sus valores en el orden en que los recibe.concatAll– Se suscribe a cada observable interno en orden y espera a que se complete antes de suscribirse al siguiente observable.
Los operadores se pueden encadenar para crear flujos de datos complejos que filtran eventos según ciertos criterios. Se pueden aplicar varios operadores al mismo observable.
Algunos de los operadores que se pueden usar en Reactive Extensions pueden resultar familiares para los programadores que usan lenguajes de programación funcional, como map, reduce, group y zip. [ 3 ] Hay muchos otros operadores disponibles en Reactive Extensions, aunque los operadores disponibles en una implementación particular para un lenguaje de programación pueden variar.
Ejemplos de operadores reactivos
Aquí tienes un ejemplo del uso de los operadores map y reduce. Creamos un observable a partir de una lista de números. El operador map multiplicará cada número por dos y devolverá un observable. El operador reduce sumará todos los números proporcionados (el valor 0 es el punto de partida). Al llamar a subscribe, se registrará un observador que observará los valores del observable generado por la cadena de operadores. Con el método subscribe, podemos pasar una función de manejo de errores, que se ejecuta cada vez que se produce un error en el observable, y una función de finalización cuando el observable ha terminado de emitir elementos.
import { of , Observable , map , reduce } from 'rxjs' ;const source : Observable <number> = of ( 1 , 2 , 3 , 4 , 5 ) ; source.pipe ( map ( ( value ) => value * 2 ) , reduce (( sum , value ) = > sum + value , 0 ) ) . subscribe ({ next : ( value ) => { console.log ( value ) ; }, error : ( error ) => { console.error ( error ) ; }, complete : () => { console.log ( ' done ' ) ; } , } );Uso en programación orientada a flujos
Ciertas primitivas de RxJS, como , BehaviorSubjectpermiten crear flujos con estado puro para rastrear el estado de la aplicación de complejidad arbitraria en términos sencillos.
El botón que aparece a continuación enviará un evento al flujo, que a su vez reemitirá el siguiente número natural cada vez, de vuelta a la etiqueta que le sigue y mostrará el recuento de clics detectados.<span>
Bibliotecas como Rimmel.js , diseñadas en torno a los Observables de RxJS, permiten la integración entre flujos reactivos y el DOM de HTML:
import { BehaviorSubject , scan } from 'rxjs' ; import { rml } from 'rimmel' ;const count = new BehaviorSubject ( 0 ). pipe ( scan ( x => x + 1 ) );document.body.innerHTML = rml ` <button onclick =" ${ counter } " >click</button> <p> El recuento es: <span> ${ counter } </span></p> ` ;Historia
Reactive Extensions fue creado por el equipo de Programabilidad en la Nube de Microsoft alrededor de 2011, como un subproducto de un proyecto más amplio llamado Volta. Originalmente, su objetivo era proporcionar una abstracción para eventos en diferentes capas de una aplicación, con el fin de facilitar la división de capas en Volta. El logotipo del proyecto representa una anguila eléctrica, en referencia a Volta. El sufijo "extensions" en el nombre alude a la tecnología Parallel Extensions , inventada casi al mismo tiempo; ambas se consideran complementarias.
La implementación inicial de Rx fue para .NET Framework y se lanzó el 21 de junio de 2011. Posteriormente, el equipo comenzó a implementar Rx para otras plataformas, incluyendo JavaScript y C++ . La tecnología se lanzó como código abierto a finales de 2012, inicialmente en CodePlex . Más tarde, el código se trasladó a GitHub y se ha adaptado a varios otros lenguajes, como Go, Java, Kotlin, PHP y Rust.
Véase también
Referencias
Enlaces externos
- ReactiveX , sitio web de extensiones reactivas con documentación y lista de implementaciones.
- ReactiveX en GitHub
- Herramientas de programación
- Software gratuito de Microsoft
- Software que utiliza la licencia Apache.
- Software que utiliza la licencia MIT.
- Software de 2011