puddlejumper26 / blogs

Personal Tech Blogs
4 stars 1 forks source link

Notes of Rxjs Library for Angular #12

Open puddlejumper26 opened 4 years ago

puddlejumper26 commented 4 years ago

RXJS is a libray for composing asunchronous and event-based programs by using observale sequences.

The core type is -- Observable The satellite types are --Observer, Schedulers,Subject The operators are -- map, filter, reduce, every, etc from JavaScript. The list in RxJS.

The essential concepts in RxJS which solve async event management are:

What makes RxJS powerful is its ability to produce values using pure functions.

The returned value of the callback will then become the next value exposed the next time the callback runs.

pure functions A pure function is a function where the return value is only determined by its input values, without observable side effects. This is how functions in math work: Math.cos(x) will, for the same value of x, always return the same result. Computing it does not change x. It does not write to log files, do network requests, ask for user input, or change program state. It’s a coffee grinder: beans go in, powder comes out, end of story.

When a function performs any other “action”, apart from calculating its return value, the function is impure.

Observables

Observables are created using new Observable or a creation operator, are subscribed to with an Observer, execute to deliver next / error / complete notifications to the Observer, and their execution may be disposed.

Observables can be created with new Observable. Most commonly, observables are created using creation functions, like of, from, interval, etc.

Along with Observables, for the events synchronously or asynchronously, there are also EventEmitter from Angular, and Promise from JS.

EventEmitter Use in components with the @Output directive to emit custom events synchronously or asynchronously, and register handlers for those events by subscribing to an instance.

Promise The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value., And it is the the most common type of Push system in JavaScript today,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).

Observables are able to deliver values either synchronously or asynchronously.

What is the difference between an Observable and a function? Observables can "return" multiple values over time, something which functions cannot.

func.call() means "give me one value synchronously"; observable.subscribe() means "give me any amount of values, either synchronously or asynchronously"

subscribe

The Observable constructor takes one argument: the subscribe function.

When observable.subscribe is called, the Observer gets attached to the newly created Observable execution. This call also returns an object, the Subscription:

Subscribing to an Observable is similar to calling a Function.

A subscribe call is simply a way to start an "Observable execution" and deliver values or events to an Observer of that execution.

The Subscription represents the ongoing execution, and has a minimal API which allows you to cancel that execution.With subscription.unsubscribe() you can cancel the ongoing execution

import { from } from 'rxjs';

const observable = from([10, 20, 30]);
const subscription = observable.subscribe(x => console.log(x));
// Later:
subscription.unsubscribe();

Just like observable.subscribe resembles new Observable(function subscribe() {...}), the unsubscribe we return from subscribe is conceptually equal to subscription.unsubscribe. In fact, if we remove the ReactiveX types surrounding these concepts, we're left with rather straightforward JavaScript.

The reason why we use Rx types like Observable, Observer, and Subscription is to get safety (such as the Observable Contract) and composability with Operators.

Higher-order Observables

Observables of Observables, so-called higher-order Observables

Operators

Operators are functions. There are two kinds of operators: Pipeable Operators and Creation Operators

  1. Pipeable Operators are the kind that can be piped to Observables using the syntax observableInstance.pipe(operator()). These include, filter(...), and mergeMap(...). When called, they do not change the existing Observable instance. Instead, they return a new Observable, whose subscription logic is based on the first Observable.

Pipes to link operators together. Pipes let you combine multiple functions into a single function. The pipe() function takes as its arguments the functions you want to combine, and returns a new function that, when executed, runs the composed functions in sequence.

A Pipeable Operator is essentially a pure function which takes one Observable as input and generates another Observable as output. Subscribing to the output Observable will also subscribe to the input Observable.

  1. Creation Operators are the other kind of operator, which can be called as standalone functions to create a new Observable. For example: of(1, 2, 3) creates an observable that will emit 1, 2, and 3, one right after another.

A set of operators applied to an observable is a recipe—that is, a set of instructions for producing the values you’re interested in. By itself, the recipe doesn’t do anything. You need to call subscribe() to produce a result through the recipe.

import { filter, map } from 'rxjs/operators';

const squareOdd = of(1, 2, 3, 4, 5)
  .pipe(
    filter(n => n % 2 !== 0),
    map(n => n * n)
  );

// Subscribe to get values
squareOdd.subscribe(x => console.log(x));

There are operators for different purposes, and they may be categorized as: creation, transformation, filtering, joining, multicasting, error handling, utility, etc.

Operator Decision Tree

Subjects

An RxJS Subject is a special type of Observable that allows values to be multicasted to many Observers.

While plain Observables are unicast (each subscribed Observer owns an independent execution of the Observable), Subjects are multicast

import { Subject } from 'rxjs';

const subject = new Subject<number>();

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

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

// Logs:
// observerA: 1
// observerB: 1
// observerA: 2
// observerB: 2

Notice the above case, the Subject has subscribe to Two Observable. Therefore it is Multicasted.