Create operator in RxJS

Keywords: Javascript less github

The creation operators in RxJs are the starting point of creating data flow. These operators can create a flow out of nothing or according to other data forms. The Observable constructor can directly create a data flow, such as:

const $source=new Observable(observer=>{
    observer.next(1);
    observer.next(2);
    observer.next(3);
})

However, this method is rarely used in real use. RxJx provides a large number of creation operators for us to use in development. Creation operators are static operators.

1, Create synchronous data flow

To synchronize the data flow, or synchronize the Observable object, you need to turn off the following: 1. What data is produced; 2. What is the order of data. For synchronous data flow, the time interval between data does not exist, so it is not necessary to consider the problem of time.

1. The simplest operator of create

It works like this:

import {Observable} from 'rxjs/Observable';

const onSubscribe=observer=>{
    observer.next(1);
    observer.next(2);
    observer.next(3);
}
const source$=Observable.create(onSubscribe);

var theObserver={
    next:item=>console.log(item)
}
// var theObserver={};
// theObserver.next=item=>console.log(item)

source$.subscribe(theObserver);//output:1,2,3

2. of enumerated data

of can create an Observable based on a specified dataset

(1) Static method creation of Observabe (this kind of static creation is to mount the of operator on the prototype of Javascript similar to that of Observable.prototype.of=of, which becomes the global function of Observable)

import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/of';

const source$=Observable.of(1,2,3);
source$.subscribe(console.log);

(2) Import package creation from rxjs/observable (this of is not directly mounted on the prototype)

import { of } from "rxjs/observable/of";
const source$=of(1,2,3);
source$.subscribe(console.log);//output 1,2,3

3. range

range can produce a continuous sequence, specifying the start value and length

import { Observable } from 'rxjs/Observable';
import { range } from 'rxjs/add/observable/range';

const source$ = Observable.range(1, 100);
source$.subscribe(console.log);//output 1 to 100

The first parameter of range can be a decimal, and the master can only increment 1 at a time

Like this

import { Observable } from 'rxjs/Observable';
import { range } from 'rxjs/add/observable/range';

const source$ = Observable.range(1.5, 100);
source$.subscribe(console.log);//output 1.5 to 100.5

4. generate generates a custom sequence

import { Observable } from "rxjs/Observable";
import { generate } from 'rxjs/add/observable/generate';

const source=Observable.generate(3,
    condation=>condation<10,
    step=>step+2,
    result=>result*result)
    .subscribe(console.log);//output 9,25,49,91

The first parameter is the initial value, the second is the ending condition, the third is the step size of each increment, and the fourth parameter is a callback processing for each result. This operator is similar to the for loop. The meaning of the above statement is the same as the following statement

for (let i = 3; i < 10; i = i + 2) {
    console.log(i * i);
}

generate is not limited to generating sequences of numbers, such as this:

Observable.generate('a',
c=>c.length<5,
s=>s+'a',
r=>r).subscribe(console.log);//a aa aaa aaaa

5. repeat data flow of duplicate data

This is an instance operator that can be imported in two ways

import {repeat} from 'rxjs/add/operator/repeat';
//or
import {repeat} from 'rxjs/operators/repeat';

The number of times the data of the upstream data flow is set repeatedly:

import {repeat} from 'rxjs/add/operator/repeat';
import  'rxjs/add/Observable/of';
import { Observable } from 'rxjs/Observable';
//or
//import {repeat} from 'rxjs/operators/repeat';

Observable.of(1,2,3)
.repeat(3)
.subscribe(console.log);//output:1,2,3 1,2,3 1,2,3

j

The upstream data stream is output three times repeatedly. In essence, repeat is achieved by repeatedly subscribing to the upstream data stream. If the upstream data stream does not complete repeat, there will be no effect.

The parameter of repeat identifies the number of repetitions. If you have to enter the expected number of repetitions, the parameter should be greater than 0. If it is less than 0, there will be infinite cycles, and the execution result of the program will be unexpected.

6. empty directly generates a finished data stream

import 'rxjs/add/observable/empty';
const source$ = Observable.empty();

7. throw directly throws an error

import 'rxjs/add/observable/throw';
const source$ = Observable.throw(new Error('Somthing error'));

Because throw is the keyword of javascript. If you don't use the static way to use the import, you can change it to "throw" to avoid conflicts with javascript keywords

import {_throw} from 'rxjs/observable/throw';
const source$ = _throw(new Error('some error'));

8. never, it's good to create an observable object, that is, it doesn't spit data or make mistakes

import 'rxjs/add/observable/never';
 const source$ = Observable.never();

The first eight operators are all synchronization operators, which generate synchronization data flow.

9. interval and timer generate data flow regularly

These two are the simplest operators to generate asynchronous data flow. They are similar to setInterval and setTimeout in javascript.

interval takes a parameter that is the number of milliseconds to generate a sequence starting at 0

import { Observable } from "rxjs/Observable";
import { interval } from "rxjs/add/observable/interval";

Observable.interval(1000).subscribe(console.log);

You can only start from 0 and increment 1 at a time. If you want to change the starting number, you can combine the map operator to implement it. Here is how to increment 1 at a time starting from 2

Observable.interval(1000).map(x=>x+2).subscribe(console.log);

The first parameter of timer can be passed to or through Date. Passing a number indicates how many milliseconds it takes to output 0. If the passed in parameter is Date, it means when the time reaches this Date, it outputs 0. The second parameter indicates the interval time. If the first parameter and the second parameter are both input, it has the same function as interval

The output of the following two statements is the same:

import { Observable } from "rxjs/Observable";
import  "rxjs/add/observable/interval";
import "rxjs/add/observable/timer";

Observable.interval(1000).subscribe(console.log);
Observable.timer(1000,1000).subscribe(console.log);

10. from can turn everything into Observable

import { Observable } from "rxjs/Observable";
import "rxjs/add/observable/from";
import "rxjs/add/observable/of";

Observable.from([1, 2, 3]).subscribe(console.log);//output:1,2,3
Observable.from("Hello").subscribe(console.log);//output:H,e,l,l,o

function toObservable() {
    return Observable.from(arguments);//In JavaScript, all arguments can be accessed through arguments in any function body
}

toObservable(1, 2, 3, 4).subscribe(console.log);//output:1,2,3,4

function * generateNumber(max) {
    for (let i = 1; i <= max; ++i)
    { yield i; }
}
Observable.from(generateNumber(3)).subscribe(console.log);//output:1,2,3

const source$=Observable.of(1,2,3);
Observable.from(source$).subscribe(console.log);//output:1,2,3

11. Handover of asynchronous processing from promise

This operator is widely used in practice.

import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/from';

const promise = Promise.resolve('successfuly');
const source$ = Observable.from(promise);
source$.subscribe(console.log, error => console.log('catch', error), () => console.log('complete'));

12.fromEvent converts DOM operations to Observable

The first parameter is the specific HTML element in the event source DOM. The second parameter is the event name such as click, mouseover, etc.

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>from event</title>
    <script src="https://unpkg.com/rxjs@5.5.2/bundles/Rx.min.js"></script>
</head>
<body>
    <div>
        <button id="btnTest">I'm button</button>
        <label id="lblTest"></label>
    </div>
    <script src="./fromEventTest.js"></script>
</body>
</html>

Javascript:

let number = 0;
Rx.Observable.fromEvent(document.querySelector('#btnTest'), 'click')
    .subscribe(x => {
        document.querySelector('#lblTest').innerText = ++number;
    });

Click the number in the button label to increase by 1

13. More flexible events from eventpattern are converted to Observable operators

fromEventPattern accepts two function parameters, which correspond to the actions when the Observable object of the production is subscribed or unsubscribed. Because these two parameters are functions, specific actions can be defined arbitrarily, so they can be flexible.

import { Observable } from "rxjs/Observable";
import { EventEmitter } from "events";
import 'rxjs/add/observable/fromEventPattern';

const emitter = new EventEmitter();

const addHandler = handler => {
    emitter.addListener('msg', handler);
}

const removeHandler = handler => {
    emitter.removeListener('msg', handler);
}
const source$ = Observable.fromEventPattern(addHandler, removeHandler);

const subscription = source$.subscribe(console.log, error => console.log("error:" + error), console.log("complete"));

emitter.emit('msg', 1);
emitter.emit('msg', '2');
emitter.emit('msg', 3);
subscription.unsubscribe();
emitter.emit('msg', 4);

14. ajax creates an Observable through the result returned by ajax

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ajax</title>
    <script src="https://unpkg.com/rxjs@5.5.2/bundles/Rx.min.js"></script>
</head>

<body>
    <div>
        <button id="btnTest">I'm button</button>
        <label id="lblTest"></label>
    </div>
    <script src="./ajax.js"></script>
</body>

</html>

Javascript

Rx.Observable.fromEvent(document.querySelector("#btnTest"), "click")
    .subscribe(y => {
        Rx.Observable.ajax("https://api.github.com/repos/ReactiveX/rxjs")
            .subscribe(x => {
                console.log(x);
                document.querySelector("#lblTest").innerText = x.response;
            }, error => {
                console.log("error:" + error);
            }, () => console.log("complete"));
    })

15. repeat when can repeatedly subscribe to the upstream data flow and set a waiting time. repeat can only repeatedly subscribe but not set a time

import { Observable } from "rxjs";

Observable.of(1,2,3).repeatWhen(()=>{
    return Observable.interval(1000);
}).subscribe(console.log);

16.defer resource call operator

import 'rxjs/add/observable/defer';
import 'rxjs/add/observable/of';
import {Observable} from 'rxjs/Observable';

const observableFactory = () => Observable.of(1, 2, 3);
const source$ = Observable.defer(observableFactory);

source$.subscribe(console.log);

Posted by brij_theinvader on Thu, 19 Mar 2020 04:46:31 -0700