RxJs 中创建操作符是创建数据流的起点,这些操作符可以凭空创建一个流或者是根据其它数据形式创建一个流。 Observable的构造函数可以直接创建一个数据流,比如:

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

但是在真正的使用过程中很少使用这种方式去创建,RxJx 提供了大量的创建操作符供我们在开发中去使用。创建型操作符打不风都是静态操作符。

一、创建同步数据流

同步数据流,或者说同步Observable对象,需要关⼼的就是: 1.产⽣哪些数据 2. 数据之间的先后顺序如何。 对于同步数据流,数据之间的时间间隔不存在,所以不需要考虑时间 ⽅⾯的问题。

1、create 最简单的操作符

它的使用像这样:

  1. import {Observable} from 'rxjs/Observable';
  2.  
  3. const onSubscribe=observer=>{
  4. observer.next(1);
  5. observer.next(2);
  6. observer.next(3);
  7. }
  8. const source$=Observable.create(onSubscribe);
  9.  
  10. var theObserver={
  11. next:item=>console.log(item)
  12. }
  13. // var theObserver={};
  14. // theObserver.next=item=>console.log(item)
  15.  
  16. source$.subscribe(theObserver);//output:1,2,3

2、of 列举数据

of 可以根据一个指定的数据集创建一个Observable

(1)Observabe 的静态方法创建(这种静态创建是将of操作符挂载在Javascript的prototype上类似这样Observable.prototype.of=of 这样就成了Observable的全局函数了)

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

(2)从rxjs/observable下导入包创建 (这种of没有直接挂载在prototype上)

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

3、range 指定范围

range可以产生一个连续的序列,指定起始值和长度

  1. import { Observable } from 'rxjs/Observable';
  2. import { range } from 'rxjs/add/observable/range';
  3.  
  4. const source$ = Observable.range(1, 100);
  5. source$.subscribe(console.log);//output 1 to 100

range 的第一个参数可以是小数,大师每次只能递增1

像这样

  1. import { Observable } from 'rxjs/Observable';
  2. import { range } from 'rxjs/add/observable/range';
  3.  
  4. const source$ = Observable.range(1.5, 100);
  5. source$.subscribe(console.log);//output 1.5 to 100.5

4、generate 产生一个定制的序列

  1. import { Observable } from "rxjs/Observable";
  2. import { generate } from 'rxjs/add/observable/generate';
  3.  
  4. const source=Observable.generate(3,
  5. condation=>condation<10,
  6. step=>step+2,
  7. result=>result*result)
  8. .subscribe(console.log);//output 9,25,49,91

第一个参数是初始值,第二个是结束的条件,第三个是每次递增的步长,第四个参数是对每次产生结果的一个回调处理,这个操作符和 for循环类似,上面的这个语句的意思是和下面的语句一样

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

generate 不限于产生数字的序列,比如像 这样:

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

5、repeat 重复数据的数据流

这个是一个实例操作符 可以通过下面两种方式导入

  1. import {repeat} from 'rxjs/add/operator/repeat';
  2. //or
  3. import {repeat} from 'rxjs/operators/repeat';

将上游的数据流的数据重复设置的次数:

  1. import {repeat} from 'rxjs/add/operator/repeat';
  2. import 'rxjs/add/Observable/of';
  3. import { Observable } from 'rxjs/Observable';
  4. //or
  5. //import {repeat} from 'rxjs/operators/repeat';
  6.  
  7. Observable.of(1,2,3)
  8. .repeat(3)
  9. .subscribe(console.log);//output:1,2,3 1,2,3 1,2,3

j

将上游数据流重复输出3次, 实质上repeat是通过重复订阅上游数据流来达到重复的效果,如果上游数据流不complete repeat就没有效果。

repeat 的参数标识重复的次数,如果必须输入预期的重复次数参数应该大于0, 如果小于0会进行无限次循环,程序的的执行结果将不可预期。

6、empty 直接产生一个完结的数据流.

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

7、throw 直接接抛出一个错误

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

因为throw 是javascript的关键字如果不用静态的方式使用导入时赢改是 _throw,避免和javascript关键字冲突

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

8、never 创建一个Obervable 对象什么都不错,即不吐数据也不出错

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

前面的8个操作符都是同步操作符,产生的都是同步数据流。

9、interval 和timer 定时产生数据流

这俩个是最简单的产生异步数据流的操作符, 它们类似javascript中的setInterval 和setTimeout。

interval接受一个参数就是产生从0开始的序列的毫秒数

  1. import { Observable } from "rxjs/Observable";
  2. import { interval } from "rxjs/add/observable/interval";
  3.  
  4. Observable.interval(1000).subscribe(console.log);

每次只能从0开始且每次只能递增1,如果想改起始数字可以结合map操作符来实现, 如下是从2开始每次递增1.

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

timer地第一个参数可以传数字也也可以穿Date,传数字表示多好毫秒输出0, 如果传入的是Date 表示时间到这个Date时输出0,第二个参数表示间隔的时间,如果第一个参数和第二个参数都输入那就和interval的功能一样了

下面这两条语句输出的结果相同:

  1. import { Observable } from "rxjs/Observable";
  2. import "rxjs/add/observable/interval";
  3. import "rxjs/add/observable/timer";
  4.  
  5. Observable.interval(1000).subscribe(console.log);
  6. Observable.timer(1000,1000).subscribe(console.log);

10、from 可以将一切转化成Observable

  1. import { Observable } from "rxjs/Observable";
  2. import "rxjs/add/observable/from";
  3. import "rxjs/add/observable/of";
  4.  
  5. Observable.from([1, 2, 3]).subscribe(console.log);//output:1,2,3
  6. Observable.from("Hello").subscribe(console.log);//output:H,e,l,l,o
  7.  
  8. function toObservable() {
  9. return Observable.from(arguments);//在JavaScript中,任何⼀个函数体中都可以通过arguments访问所有的调 ⽤参数
  10. }
  11.  
  12. toObservable(1, 2, 3, 4).subscribe(console.log);//output:1,2,3,4
  13.  
  14. function * generateNumber(max) {
  15. for (let i = 1; i <= max; ++i)
  16. { yield i; }
  17. }
  18. Observable.from(generateNumber(3)).subscribe(console.log);//output:1,2,3
  19.  
  20. const source$=Observable.of(1,2,3);
  21. Observable.from(source$).subscribe(console.log);//output:1,2,3

11.fromPromise 异步处理的交接

这操作符在实际使用中用的非常多。

  1. import { Observable } from "rxjs/Observable";
  2. import 'rxjs/add/observable/from';
  3.  
  4. const promise = Promise.resolve('successfuly');
  5. const source$ = Observable.from(promise);
  6. source$.subscribe(console.log, error => console.log('catch', error), () => console.log('complete'));

12.fromEvent 将对DOM的操作转化成Observable

第一个参数是事件源DOM 中就是具体的HTML元素,第二个参数是事件名称 如:click,mouseover等。

HTML:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>from event</title>
  7. <script src="https://unpkg.com/rxjs@5.5.2/bundles/Rx.min.js"></script>
  8. </head>
  9. <body>
  10. <div>
  11. <button id="btnTest">I'm button</button>
  12. <label id="lblTest"></label>
  13. </div>
  14. <script src="./fromEventTest.js"></script>
  15. </body>
  16. </html>

Javascript:

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

点击按钮label中的数字递增1.

13、fromEventPattern 更灵活的事件转化成Observable操作符

fromEventPattern接受两个函数参数,分别对应产⽣的Observable对象 被订阅和退订时的动作,因为这两个参数是函数,具体的动作可以任意定 义,所以可以⾮常灵活。

  1. import { Observable } from "rxjs/Observable";
  2. import { EventEmitter } from "events";
  3. import 'rxjs/add/observable/fromEventPattern';
  4.  
  5. const emitter = new EventEmitter();
  6.  
  7. const addHandler = handler => {
  8. emitter.addListener('msg', handler);
  9. }
  10.  
  11. const removeHandler = handler => {
  12. emitter.removeListener('msg', handler);
  13. }
  14. const source$ = Observable.fromEventPattern(addHandler, removeHandler);
  15.  
  16. const subscription = source$.subscribe(console.log, error => console.log("error:" + error), console.log("complete"));
  17.  
  18. emitter.emit('msg', 1);
  19. emitter.emit('msg', '2');
  20. emitter.emit('msg', 3);
  21. subscription.unsubscribe();
  22. emitter.emit('msg', 4);

14、ajax 通过ajax 返回的结果 创建一个Observable

  1. <!DOCTYPE html>
  2. <html lang="en">
  3.  
  4. <head>
  5. <meta charset="UTF-8">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>ajax</title>
  8. <script src="https://unpkg.com/rxjs@5.5.2/bundles/Rx.min.js"></script>
  9. </head>
  10.  
  11. <body>
  12. <div>
  13. <button id="btnTest">I'm button</button>
  14. <label id="lblTest"></label>
  15. </div>
  16. <script src="./ajax.js"></script>
  17. </body>
  18.  
  19. </html>

Javascript

  1. Rx.Observable.fromEvent(document.querySelector("#btnTest"), "click")
  2. .subscribe(y => {
  3. Rx.Observable.ajax("https://api.github.com/repos/ReactiveX/rxjs")
  4. .subscribe(x => {
  5. console.log(x);
  6. document.querySelector("#lblTest").innerText = x.response;
  7. }, error => {
  8. console.log("error:" + error);
  9. }, () => console.log("complete"));
  10. })

15、repeatWhen反复订阅上游的数据流并且可以设置一个等待的时间,repeat 只能反复订阅不能设置时间

  1. import { Observable } from "rxjs";
  2.  
  3. Observable.of(1,2,3).repeatWhen(()=>{
  4. return Observable.interval(1000);
  5. }).subscribe(console.log);

16.defer 延迟资源调用操作符

  1. import 'rxjs/add/observable/defer';
  2. import 'rxjs/add/observable/of';
  3. import {Observable} from 'rxjs/Observable';
  4.  
  5. const observableFactory = () => Observable.of(1, 2, 3);
  6. const source$ = Observable.defer(observableFactory);
  7.  
  8. source$.subscribe(console.log);

RxJS 中的创建操作符的更多相关文章

  1. js中的new操作符与Object.create()的作用与区别

    js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...

  2. 【转载】如何在Android中避免创建不必要的对象

    在编程开发中,内存的占用是我们经常要面对的现实,通常的内存调优的方向就是尽量减少内存的占用.这其中避免创建不必要的对象是一项重要的方面. Android设备不像PC那样有着足够大的内存,而且单个App ...

  3. Rxjava2实战--第三章 创建操作符

    Rxjava2实战--第三章 创建操作符 Rxjava的创建操作符 操作符 用途 just() 将一个或多个对象转换成发射这个或者这些对象的一个Observable from() 将一个Iterabl ...

  4. dart系列之:dart语言中的特殊操作符

    dart系列之:dart语言中的特殊操作符 目录 简介 普通操作符 类型测试操作符 条件运算符 级联符号 类中的自定义操作符 总结 简介 有运算就有操作符,dart中除了普通的算术运算的操作符之外,还 ...

  5. 内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例

    内部类访问外部类的变量必须是final吗? 如下: package com.java.concurrent; class A { int i = 3; public void shout() { cl ...

  6. HTML5 UI框架Kendo UI Web中如何创建自定义组件(二)

    在前面的文章<HTML5 UI框架Kendo UI Web自定义组件(一)>中,对在Kendo UI Web中如何创建自定义组件作出了一些基础讲解,下面将继续前面的内容. 使用一个数据源 ...

  7. oracle中如何创建dblink

    当用户要跨本地数据库,访问另外一个数据库表中的数据时,本地数据库中必须创建了远程数据库的dblink,通过dblink本地数据库可以像访问本地数据库一样访问远程数据库表中的数据.下面讲介绍如何在本地数 ...

  8. SQL server 表中如何创建索引?

    SQL server 表中如何创建索引?看个示例,你就会了 use master goif db_id(N'zhangxu')is not nulldrop database zhangxugocre ...

  9. C#中如何利用操作符重载和转换操作符

    操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...

随机推荐

  1. shell之路 shell核心语法【第一篇】shell初识

    shell简介 1.Shell是Unix的脚本语言,是与 Unix/Linux 交互的工具,shell使用的熟练程度反映了用户对Unix/Linux使用的熟练程度 2.Shell是系统命令+程序逻辑的 ...

  2. centos7 安装高版本svn

    一.安装高版本svn 1.创建一个新的yum库文件,vim /etc/yum.repos.d/wandisco-svn.repo 内容如下 [WandiscoSVN] name=Wandisco SV ...

  3. 进程间通信之socketpair

    socketpair是进程间通信的一种方式. API: ]); DEMO: #include <stdio.h> #include <stdlib.h> #include &l ...

  4. P3983 赛斯石(双背包)

    这题不算难的,但是脑子真的特别乱.....传送门 \(Ⅰ.物品可以拆开来但船不能拆开来,所以1-10载重船的最大收益完全可以用背包求出来.\) \(Ⅱ.最后一定是选一些船走,而船的收益已经固定.所以用 ...

  5. L - A Heap of Heaps CodeForces - 538F 主席树

    L - A Heap of Heaps CodeForces - 538F 这个是一个还比较裸的静态主席树. 这个题目的意思是把这个数组变成k叉树,然后问构成的树的子树小于等于它的父节点的对数有多少. ...

  6. S - Query on a tree HDU - 3804 线段树+dfs序

    S - Query on a tree HDU - 3804   离散化+权值线段树 题目大意:给你一棵树,让你求这棵树上询问的点到根节点直接最大小于等于val的长度. 这个题目和之前写的那个给你一棵 ...

  7. Java 8 CompletableFuture思考

    Java 8 CompletableFuture思考 最近一直在用响应式编程写Java代码,用的框架大概上有WebFlux(Spring).R2dbc.Akka...一些响应式的框架. 全都是Java ...

  8. NetCore项目实战篇04---集成IdentityService4

    大家都知道我们的项目中已有web api,现在可以正式访问,不论任何人只要通过输入对应的api网址就可以访问到我们的api 资源,这样是很不安全的,我们需求对当前用户进行身份验证,因此我们在项目中使用 ...

  9. dbcp数据源连接池

    一.数据源连接池 我们之前利用jdbc连接数据库,每次都要创建连接对象,销毁连接对象,如果并发访问量比较大,这样肯定比较辣 浪费数据库的效率,我们可以像之前mybatis中缓存查询到的数据一样,可以把 ...

  10. input唤起键盘影响移动端底部fixed定位

    主要代码如下: public docmHeight = document.documentElement.clientHeight || document.body.clientHeight; // ...