https://rxjs.dev/guide/overview

Without any promise abstractions, the intrinsic nature that a promise can only be resolved once makes it not immediately easy to fire off a sequence of async steps in response to a stimulus (like an event) that can in fact happen multiple times, like a button click.
One option is to start one promise chain in response to each event fire:

1
2
3
4
5
6
handleClick( "#mybtn", function(){
request( "http://some.url.1/")
.then( function(text){
console.log( text );
} );
} );

Libraries like RsJS provide an abstraction that creates an observable pattern. With RxJS, same result can be achieved by:

1
2
3
4
5
6
7
8
9
import { fromEvent } from 'rxjs';

const observable = fromEvent(document, 'click')
observable.subscribe(() => {
request( "http://some.url.1/")
.then( function(text){
console.log( text );
} )
});

fromEvent creates an observable from event, and it can synchronously or asynchronously return zero to (potentially) infinite values from the time it’s invoked onwards.

Every JavaScript Function is a Pull system. The function is a Producer of data, and the code that calls the function is consuming it by “pulling” out a single return value from its call.

Promises are the most common type of Push system in JavaScript today. A Promise (the Producer) delivers a resolved value to registered callbacks (the Consumers), but unlike functions, it is the Promise which is in charge of determining precisely when that value is “pushed” to the callbacks.

RxJS introduces Observables, a new Push system for JavaScript. An Observable is a Producer of multiple values, “pushing” them to Observers (Consumers).

There’s also subject and its variations that is observable that multicasts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { AsyncSubject } from 'rxjs';
const subject = new AsyncSubject();

subject.subscribe({
next: (v) => console.log(`observerA: ${v}`),
});

subject.next(1);
subject.next(2);
subject.next(3);
subject.next(4);

subject.subscribe({
next: (v) => console.log(`observerB: ${v}`),
});

subject.next(5);
subject.complete();