ventajas tutorial reactivas reactiva programacion libro desventajas arquitectura aplicaciones javascript reactive-programming rxjs bacon.js elm

tutorial - ¿La programación reactiva funcional en JavaScript causa mayores problemas con las referencias de los oyentes?



tutorial programacion reactiva (1)

En JavaScript, el patrón de observador se utiliza con bastante frecuencia. Hay una cosa difícil con eso y esas son las referencias que el sujeto guarda de los observadores. Requieren limpieza. Para aplicaciones regulares utilizo las siguientes reglas generales:

  • Si el sujeto tiene una vida útil más corta que (o igual a) el observador, solo puedo hacer subject.on(''event'', ...)
  • Si el sujeto tiene una vida útil más larga que el observador, necesito usar observer.listenTo(subject, ''event'', ...)

En el segundo caso, el listenTo es consciente del ciclo de vida del observador y eliminará automáticamente a los oyentes cuando sea el momento de que el observador muera.

En el estilo moderno de SPA (aplicación de una sola página), donde solo algunas partes de la aplicación están activas en cualquier momento, esto es algo que se vuelve muy importante. Si lo combina con sockets web, que son un candidato perfecto para un flujo de eventos y lo más probable es que sea de larga duración, esto se vuelve aún más importante.

Con FRP, teniendo algo como un flujo de eventos que representa valores cambiantes a lo largo del tiempo, estoy (sin saberlo) creando muchos oyentes. Cada filter , map y map flatMap crea un nuevo flujo que está vinculado (probablemente utilizando un oyente) al anterior.

En mi opinión, parece bastante difícil determinar cómo y cuándo necesito eliminar a esos oyentes. No puedo imaginarme siendo el primero en pensar en este problema, pero no pude encontrar mucho sobre esto en Internet.

He visto que algunos marcos en otros idiomas usan referencias débiles. JavaScript no tiene el concepto de referencias débiles (WeakMap no se puede usar aquí). Sin embargo, aunque lo haya hecho, parece una mala idea porque no está claro cuándo tendrá lugar la recolección de basura.

  • ¿Cómo se resuelve esto en los marcos actuales?
  • ¿Los marcos se vinculan con el ciclo de vida de los objetos? Si es así, ¿cómo?

En RxJs, cada Observer tendrá, por defecto, un oyente por separado en el origen del evento original. Así que, si tienes

var s = $(''#textInput'').keyupAsObservable() s.subscribe(subscriber1); s.map(function() {}).subscribe(subscriber2);

Tendrás dos oyentes keyup. Puede usar .publish().refCount() para hacer que un Observable mantenga una única conexión a su fuente.

En Bacon.js, los Observables siempre mantienen una única conexión a su fuente.

En ambas bibliotecas, la conexión a la fuente se crea perezosamente (cuando se agrega un Observer ) y se elimina automáticamente cuando se elimina el (último) observador. Por lo tanto, no es necesario administrar manualmente los oyentes.

Sin embargo, en el caso de que el subject tenga una vida útil más larga que el Observer , deberá asegurarse de que el observador interrumpa su suscripción cuando finalice su vida útil, o tendrá una fuga. Ninguna de las bibliotecas tiene una forma "mágica" de gestionar esto, porque para la biblioteca, su Observer es solo una función.

Personalmente, a menudo creo un Observable llamado death o lo que sea para indicar el fin de la vida útil del Observador y luego, en lugar de suscribirme al subject me suscribo a subject.takeUntil(death) .

Con respecto a Elm, tengo entendido que ha configurado toda la red de eventos a la vez, por lo que no hay posibilidad de fugas; Observers no se pueden agregar en una etapa posterior.