DEV Community

Cover image for 4 Laws of RxJS Observables

4 Laws of RxJS Observables

Daniel Glejzner on November 02, 2023

This is crucial to understand! Online materials can often be incorrect. Very short but meaty writeup. 🏆 Here are 4 Laws of Observables...
Collapse
 
artxe2 profile image
Yeom suyun

I have never used rxjs in a real app.
However, I don't find the arguments for its usefulness very convincing.
The biggest reason is that JavaScript is single-threaded, so there is no data race.
Are there any use cases where rxjs is really helpful?

Collapse
 
lifaon74 profile image
valentin

Here's a link explaining reactive programming: core.lirx.org/docs/documentation/g...

The purpose is to work with async code. JS is single threaded as you said, and this is especially why async (Promise, Observable, EventListener) are so well integrated in the language's APIs as we MUST have a way to order and manage tasks to avoir freezing the main thread.
Reactive programming expresses its full power when mastering it, which is, to be honest, not an easy task, as it it a totally different paradigm. However, it solves a lot of async issues: avoids typical concurrency problems, automatically updated variables, etc...
This is why current front-end frameworks like react, angular, vue, svelte tends to add more and more reactivity (useSignal, useState, signal, etc...)

Collapse
 
artxe2 profile image
Yeom suyun

Thank you for your detailed answer.
However, I think my question was a bit lacking.
Rxjs has a relatively steep learning curve due to its large number of operators and paradigm differences.
The rxjs.umd.min.js file on npm is 88kb, which is even larger than jQuery.
Even if we ignore these drawbacks and don't convert events to streams, JavaScript can easily implement things like ensuring the order of asynchronous logic, debouncing, and throttling.
Therefore, I'm curious if there are any cases where RxJS is really useful.

For example, a few months ago, I searched for "Rxjs Complex example" on Google and found a source code with the same title.
However, that example could be easily implemented without RxJS, as follows.
Using async-lube instead of Rx.js

Thread Thread
 
lifaon74 profile image
valentin

I think the first step is to view the distinction between the different paradigms. Usually developers learn imperative programming. Here we speak of something completely different: reactive programming. More paradigms exist like functional programming but it's another topic. You way somehow compare it with the introduction of Promises which changed many things.

RxJs is a framework to code in reactive programming, but you may use another. Somehow, has I said, svelte or react provide tools too to use reactive programming.

Now let's explain what reactive programming solves: applications with very complex state, and very complex stream of data. When you'll work with applications having 100k lines or more, it becomes critical to have a good engine to manage a perfect consistency.
Reactive programming through Stores are a solution, as well as RxJs.
In such an application you'll encounter a lot of values (variables) depending on others (a variable computed from another + taking some data from two different API calls fo example). Here we speak about: stream aggregation, stream switching, and dynamic computed values, but many more complex use cases exist.
With reactive programming, you'll be sure to have always the correct values, automatically updated, with a perfect consistency.

About the size now: yes the lib is not light, BUT, you'll be able to do the same thing in 5-10 lines of code instead of 50+ lines of code in imperative programming, so for big applications as well as maintenance this makes a big difference.

Finally, about complex examples, I don't think it can exist. The purpose of an example is to be understandable by everyone. But complex RxJs examples would require high understanding of the framework, so it won't be relevant. Maybe, you could use chatgpt to interact with it and give you examples with explanations or take a look at the Wikipedia page en.m.wikipedia.org/wiki/Reactive_p...

However, if you want some simple example, I've created a website giving you an usecase
core.lirx.org/docs/documentation/e... . Take a look, I hoped I helped you, and any feedback is welcome 🤗

Thread Thread
 
cesard profile image
César

Going really reactive in Angular, for example, is hard to think without RxJs... I've used it EXTENSIVELY over there and now I couldn't think of working any other way in Angular... Well, at least until Signals become prod ready...
Also, RxJs becomes easier to use and understand when you get to know the usual recipes for the usual most common scenarios, like for an autocomplete, where you know you have to pipe debounceTime, distinctUntilChanges, switchMap most of the times, and with just a couple lines of code whereas in react or others is a lot more code, much more error prone and harder to maintain.
Yes, steep curve, but once you're in, it's hard to leave.

Good explanations, btw.

Thread Thread
 
artxe2 profile image
Yeom suyun

I liked the examples you provided.
I have my doubts about the usefulness of RxJS, but it doesn't seem to matter that the library used in the example is @lirx/core.
My point is not about reactive vs imperative.
It's about streams vs events.
For example, the example you provided with lirx can be written as follows

// @lirx/core
import {
  fromEventTarget,
  function$$,
  interval,
  map$$,
  merge,
  reference,
} from '@lirx/core';

const locale$ = merge([
  reference(() => selectElement.value),
  map$$(fromEventTarget(selectElement, 'change'), () => selectElement.value),
]);
const date$ = map$$(interval(1000), () => Date.now());
const output$ = function$$([locale$, date$], formatDate);
output$((value: string) => {
  outputElement.value = value;
});
Enter fullscreen mode Exit fullscreen mode
// naive
function createSignal<T>(init: T, handler: Function) {
  return {
    get value() {
      return init;
    },
    set value(value) {
      init = value;
      handler();
    },
  };
}
let react = () => (outputElement.value = formatDate(locale.value, date.value));
let locale = createSignal(selectElement.value, react);
let date = createSignal(0, react);
selectElement.addEventListener('change', (event) => {
  locale.value = (event.target as HTMLInputElement).value;
});
setInterval(() => (date.value = Date.now()), 1000);
Enter fullscreen mode Exit fullscreen mode

The naive example shows that reactive can be applied to local and date without additional learning curve, and change the value with onchage and setInterval event, respectively.

Collapse
 
boilertom90 profile image
Tom Hoffman

If you haven’t used rxjs in an angular app, that’s a pretty simple, non-interactive app.

Collapse
 
cesard profile image
César

Or a hard-to-maintain one written in the imperative way... 😉

Collapse
 
maxime1992 profile image
Maxime

Law 1: All Observables are lazy, without exception

A BehaviorSubject reading this post:

Image description

Collapse
 
hanss profile image
Hans Schenker

The big merit of Angular having made known Typescript and RxJs to the Web World.
Typescript and RxJs are so deep rooted in science that will outlive any Web Framework