RxJS 中的创建操作符

RxJs 中创建操作符是创建数据流的起点,这些操作符可以凭空创建一个流或者是根据其它数据形式创建一个流。 Observable的构造函数可以直接创建一个数据流,比如:
const $source=new Observable(observer=>{
observer.next(1);
observer.next(2);
observer.next(3);
})
但是在真正的使用过程中很少使用这种方式去创建,RxJx 提供了大量的创建操作符供我们在开发中去使用。创建型操作符打不风都是静态操作符。
一、创建同步数据流
同步数据流,或者说同步Observable对象,需要关⼼的就是: 1.产⽣哪些数据 2. 数据之间的先后顺序如何。 对于同步数据流,数据之间的时间间隔不存在,所以不需要考虑时间 ⽅⾯的问题。
1、create 最简单的操作符
它的使用像这样:
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 列举数据
of 可以根据一个指定的数据集创建一个Observable
(1)Observabe 的静态方法创建(这种静态创建是将of操作符挂载在Javascript的prototype上类似这样Observable.prototype.of=of 这样就成了Observable的全局函数了)
import { Observable } from "rxjs/Observable";
import 'rxjs/add/observable/of';
const source$=Observable.of(1,2,3);
source$.subscribe(console.log);
(2)从rxjs/observable下导入包创建 (这种of没有直接挂载在prototype上)
import { of } from "rxjs/observable/of";
const source$=of(1,2,3);
source$.subscribe(console.log);//output 1,2,3
3、range 指定范围
range可以产生一个连续的序列,指定起始值和长度
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
range 的第一个参数可以是小数,大师每次只能递增1
像这样
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 产生一个定制的序列
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
第一个参数是初始值,第二个是结束的条件,第三个是每次递增的步长,第四个参数是对每次产生结果的一个回调处理,这个操作符和 for循环类似,上面的这个语句的意思是和下面的语句一样
for (let i = 3; i < 10; i = i + 2) {
console.log(i * i);
}
generate 不限于产生数字的序列,比如像 这样:
Observable.generate('a',
c=>c.length<5,
s=>s+'a',
r=>r).subscribe(console.log);//a aa aaa aaaa
5、repeat 重复数据的数据流
这个是一个实例操作符 可以通过下面两种方式导入
import {repeat} from 'rxjs/add/operator/repeat';
//or
import {repeat} from 'rxjs/operators/repeat';
将上游的数据流的数据重复设置的次数:
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
将上游数据流重复输出3次, 实质上repeat是通过重复订阅上游数据流来达到重复的效果,如果上游数据流不complete repeat就没有效果。
repeat 的参数标识重复的次数,如果必须输入预期的重复次数参数应该大于0, 如果小于0会进行无限次循环,程序的的执行结果将不可预期。
6、empty 直接产生一个完结的数据流.
import 'rxjs/add/observable/empty';
const source$ = Observable.empty();
7、throw 直接接抛出一个错误
import 'rxjs/add/observable/throw';
const source$ = Observable.throw(new Error('Somthing error'));
因为throw 是javascript的关键字如果不用静态的方式使用导入时赢改是 _throw,避免和javascript关键字冲突
import {_throw} from 'rxjs/observable/throw';
const source$ = _throw(new Error('some error'));
8、never 创建一个Obervable 对象什么都不错,即不吐数据也不出错
import 'rxjs/add/observable/never';
const source$ = Observable.never();
前面的8个操作符都是同步操作符,产生的都是同步数据流。
9、interval 和timer 定时产生数据流
这俩个是最简单的产生异步数据流的操作符, 它们类似javascript中的setInterval 和setTimeout。
interval接受一个参数就是产生从0开始的序列的毫秒数
import { Observable } from "rxjs/Observable";
import { interval } from "rxjs/add/observable/interval";
Observable.interval(1000).subscribe(console.log);
每次只能从0开始且每次只能递增1,如果想改起始数字可以结合map操作符来实现, 如下是从2开始每次递增1.
Observable.interval(1000).map(x=>x+2).subscribe(console.log);
timer地第一个参数可以传数字也也可以穿Date,传数字表示多好毫秒输出0, 如果传入的是Date 表示时间到这个Date时输出0,第二个参数表示间隔的时间,如果第一个参数和第二个参数都输入那就和interval的功能一样了
下面这两条语句输出的结果相同:
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 可以将一切转化成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);//在JavaScript中,任何⼀个函数体中都可以通过arguments访问所有的调 ⽤参数
}
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.fromPromise 异步处理的交接
这操作符在实际使用中用的非常多。
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 将对DOM的操作转化成Observable
第一个参数是事件源DOM 中就是具体的HTML元素,第二个参数是事件名称 如:click,mouseover等。
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;
});
点击按钮label中的数字递增1.
13、fromEventPattern 更灵活的事件转化成Observable操作符
fromEventPattern接受两个函数参数,分别对应产⽣的Observable对象 被订阅和退订时的动作,因为这两个参数是函数,具体的动作可以任意定 义,所以可以⾮常灵活。
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 通过ajax 返回的结果 创建一个Observable
<!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、repeatWhen反复订阅上游的数据流并且可以设置一个等待的时间,repeat 只能反复订阅不能设置时间
import { Observable } from "rxjs";
Observable.of(1,2,3).repeatWhen(()=>{
return Observable.interval(1000);
}).subscribe(console.log);
16.defer 延迟资源调用操作符
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);
RxJS 中的创建操作符的更多相关文章
- js中的new操作符与Object.create()的作用与区别
js中的new操作符与Object.create()的作用与区别 https://blog.csdn.net/mht1829/article/details/76785231 2017年08月06日 ...
- 【转载】如何在Android中避免创建不必要的对象
在编程开发中,内存的占用是我们经常要面对的现实,通常的内存调优的方向就是尽量减少内存的占用.这其中避免创建不必要的对象是一项重要的方面. Android设备不像PC那样有着足够大的内存,而且单个App ...
- Rxjava2实战--第三章 创建操作符
Rxjava2实战--第三章 创建操作符 Rxjava的创建操作符 操作符 用途 just() 将一个或多个对象转换成发射这个或者这些对象的一个Observable from() 将一个Iterabl ...
- dart系列之:dart语言中的特殊操作符
dart系列之:dart语言中的特殊操作符 目录 简介 普通操作符 类型测试操作符 条件运算符 级联符号 类中的自定义操作符 总结 简介 有运算就有操作符,dart中除了普通的算术运算的操作符之外,还 ...
- 内部类访问外部类的变量必须是final吗,java静态方法中不能引用非静态变量,静态方法中不能创建内部类的实例
内部类访问外部类的变量必须是final吗? 如下: package com.java.concurrent; class A { int i = 3; public void shout() { cl ...
- HTML5 UI框架Kendo UI Web中如何创建自定义组件(二)
在前面的文章<HTML5 UI框架Kendo UI Web自定义组件(一)>中,对在Kendo UI Web中如何创建自定义组件作出了一些基础讲解,下面将继续前面的内容. 使用一个数据源 ...
- oracle中如何创建dblink
当用户要跨本地数据库,访问另外一个数据库表中的数据时,本地数据库中必须创建了远程数据库的dblink,通过dblink本地数据库可以像访问本地数据库一样访问远程数据库表中的数据.下面讲介绍如何在本地数 ...
- SQL server 表中如何创建索引?
SQL server 表中如何创建索引?看个示例,你就会了 use master goif db_id(N'zhangxu')is not nulldrop database zhangxugocre ...
- C#中如何利用操作符重载和转换操作符
操作符重载 有的编程语言允许一个类型定义操作符应该如何操作类型的实例,比如string类型和int类型都重载了(==)和(+)等操作符,当编译器发现两个int类型的实例使用+操作符的时候,编译器会生成 ...
随机推荐
- Scrapy爬虫快速入门
安装Scrapy Scrapy是一个高级的Python爬虫框架,它不仅包含了爬虫的特性,还可以方便的将爬虫数据保存到csv.json等文件中. 首先我们安装Scrapy. pip install sc ...
- 从零开始通过webhooks实现前端自动化
1. 前置条件 有一台自己的服务器.比如阿里云,腾讯云之类 有远程仓库能够push代码,pull代码.比如github,或者码云 远程仓库有webhooks功能 2. 自动化部署流程 3. 构建流程 ...
- [Linux] Hexo 搭建个人博客
不做笔记出了bug就得重新再看一遍视频 视频来源: https://www.bilibili.com/video/BV1Yb411a7ty?t=75 安装 先安装 nodejs,npm, git 安装 ...
- 关于使用ffmpeg的一些牢骚
一.啰嗦几句 好几年不写博客了,一是工作计算机都加密了没法编辑提交:二是各种语言混用,什么都会就是什么都不会,delphi.c#.vb.python.c++要说我精通啥,啥也不精,所以不敢乱写. 最近 ...
- gulp插件学习01
1.安装和使用 安装node环境:官网:https://nodejs.org: 命令行输入 npm i gulp -g ,gulp-v查看安装是否成功: 创建项目目录: 进入目录,并在目录中按住shi ...
- java基础 之 从Class.forName()跟.class的区别看类的初始化
代码如下: public class Test { public static void main(String[] args) throws Exception { System.out.print ...
- 13_JavaScript基础入门(3)
条件分支语句 条件分支语句,也叫作条件判断语句,就是根据某种条件执行某些语句,不执行某些语句. JS中有三种语法是可以表示条件分支的. 1.if--else-- 条件分支的主力语法,这个主力语法能够书 ...
- python语法学习第五天--函数(2)
命名空间: 命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的. 命名空间提供了在项目中避免名字冲突的一种方法.各个命名空间是独立的,没有任何关系 ...
- [hdu5213]容斥原理+莫队算法
题意:给一个序列a,以及K,有Q个询问,每个询问四个数,L,R,U,V, 求L<=i<=R,U<=j<=V,a[i]+a[j]=K的(i, j)对数(题目保证了L <= ...
- select嵌套问题
关于sql语句: SELECT COUNT(ID) FROM dbo.N_Order_BusinessBatch WHERE Mobile='15210235082' And CreateTime=( ...