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);