6. Observable 和 数组的区别
Observable 和 数组都有filter, map 等运算操作operators,具体的区别是什么?
主要是两点:
- 延迟运算
- 渐进式取值
延迟运算
延迟运算很好理解,所有 Observable 一定会等到订阅后才开始对元素做运算,如果没有订阅就不会有运算的行为
var source = Rx.Observable.from([1,2,3,4,5]);
var example = source.map(x => x + 1);
上面这段代码因为 Observable 还没有被订阅,所以不会真的对元素做运算,这跟数组的操作不一样,如下
var source = [1,2,3,4,5];
var example = source.map(x => x + 1);
上面这段代码执行完,example 就已经取得所有元素的返回值了。
数组的运算都必须完整的运算出每个元素的返回值并组成一个新数组,再做下一个运算。
渐进式取值
数组的 operators 都必须完整的运算出每个元素的返回值并组成一个数组,再做下一个 operator 的运算,我们看下面这段程式码
var source = [1,2,3];
var example = source.filter(x => x % 2 === 0) // 这裡会运算并返回一个完整的数组.map(x => x + 1) // 这裡也会运算并返回一个完整的数组
上面这段代码,相信读者们都很熟悉了,大家应该都有注意到 source.filter(...)
就会返回一整个新数组,再接下一个 operator 又会再返回一个新的数组,这一点其实在我们实作 map 跟 filter 时就能观察到
Array.prototype.map = function(callback) {var result = []; // 建立新数组this.forEach(function(item, index, array) {result.push(callback(item, index, array))});return result; // 返回新数组
}
每一次的 operator 的运算都会建立一个新的数组,并在每个元素都运算完后返回这个新数组,我们可以用下面这张动态图表示运算过程
Observable operator 的运算方式跟数组的是完全的不同,虽然 Observable 的 operator 也都会回传一个新的 observable,但因为元素是渐进式取得的关系,所以每次的运算是一个元素运算到底,而不是运算完全部的元素再返回。
var source = Rx.Observable.from([1,2,3]);
var example = source.filter(x => x % 2 === 0).map(x => x + 1)example.subscribe(console.log);
上面这段程式码运行的方式是这样的
- 送出
1
到 filter 被过滤掉 - 送出
2
到 filter 在被送到 map 转成3
,送到 observerconsole.log
印出 - 送出
3
到 filter 被过滤掉
每个元素送出后就是运算到底,在这个过程中不会等待其他的元素运算。这就是渐进式取值的特性,不知道读者们还记不记得我们在讲 Iterator 跟 Observer 时,就特别强调这两个 Pattern 的共同特性是渐进式取值,而我们在实作 Iterator 的过程中其实就能看出这个特性的运作方式
class IteratorFromArray {constructor(arr) {this._array = arr;this._cursor = 0;}next() {return this._cursor < this._array.length ?{ value: this._array[this._cursor++], done: false } :{ done: true };}map(callback) {const iterator = new IteratorFromArray(this._array);return {next: () => {const { done, value } = iterator.next();return {done: done,value: done ? undefined : callback(value)}}}}
}var myIterator = new IteratorFromArray([1,2,3]);
var newIterator = myIterator.map(x => x + 1);
newIterator.next(); // { done: false, value: 2 }
虽然上面这段代码是一个非常简单的示范,但可以看得出来每一次 map 虽然都会返回一个新的 Iterator,但实际上在做元素运算时,因为渐进式的特性会使一个元素运算到底,Observable 也是相同的概念,我们可以用下面这张动态图表示运算过程
渐进式取值的观念在 Observable 中其实非常的重要,这个特性也使得 Observable 相较于 Array 的 operator 在做运算时来的高效很多,尤其是在处理大量资料的时候会非常明显!
(想像一下我们今天要切五万个大蛋糕,你会选择切完一个请一个人拿走,还是全部切完再拿给所有人呢?哪个会比较有效率呢?)
6. Observable 和 数组的区别相关推荐
- char *a 和char a[] 的区别(指针和数组的区别)
2019独角兽企业重金招聘Python工程师标准>>> 在C/C++中,指针和数组在很多地方可以互换使用,这使得我们产生一种错觉,感觉数组和指针两者是完全等价的,事实上数组和指针是有 ...
- JavaScript中的数组与伪数组的区别
在JavaScript中,除了5种原始数据类型之外,其他所有的都是对象,包括函数(Function). 基本数据类型:String,boolean,Number,Undefined, Null 引用数 ...
- 指针数组、数组指针、数组的区别与联系
指针数组.数组指针.数组的区别与联系! 一:基本定义 1.指针数组 char *arr[4] = {"hello", "world", "shannx ...
- java怎么把随机数放入数组_Java学习:集合的使用与数组的区别
ArrayList 集合 ArrayList 集合 ArrayList list = new ArrayList<>(); 对于ArrayList来说,有一个尖括号代表泛型. 泛型:也就是 ...
- C++指针和数组的区别(不能混用的情况)
通常情况下,C++中指针和数组是可以混用的,但是,在编写字符数组的全排列的时候,混用却出了问题,因此,今天特地mark一下,以备日后查找 这里整理的,不包括用new开辟的动态数组 1.数组一旦声明,我 ...
- 一维数组和二维数组的区别_数组指针和指针数组的区别
数组指针和指针数组的区别 - hongcha_717 - 博客园www.cnblogs.com 数组指针(也称行指针) 定义 int (*p)[n]; ()优先级高,首先说明p是一个指针,指向一个整 ...
- 字节字符区别Java_【JAVA基础】字符数组与字节数组的区别
String.getBytes()和String.tocharArray(),字节数组和字符数组的区别 String.getBytes()是将字符串转化为一个字节数组.而String.toCharAr ...
- C语言 指针数组和数组指针区别 - C语言零基础入门教程
目录 一.简介 1.数组 2.指针 3.指针和数组区别 二.指针数组和数组指针区别 1.指针数组 2.数组指针 三.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 >> ...
- json字符串,JSON对象,JSON数组的区别与相互转换
JSON数组,json字符串,JSON对象,数组的区别与基本操作整理 JSON对象是直接可以使用JQuery操作的格式 JSON字符串仅仅只是一个字符串,一个整体,不截取的话没办法取出其中存储的数据, ...
最新文章
- 经典C语言程序100例之七九
- 带有Gluon Ignite和Dagger的JavaFX中的依赖注入
- 工业以太网交换机的产品性能有哪些呢?
- MOSS数据库服务器迁移步骤
- 【Elasticsearch】 海量 分词器 在线地址 与文档
- Windows系统端口占用,使用命令行查找并杀进程
- python查询手册_Python 手册
- MYSQL数据库管理与应用
- 4.3 Matplotlib 图中图
- worldPress数据库
- 【techQA】如何在Mac OS 11 Big Sur or M1芯片Mac下开启蓝牙Apt-X
- 什么是adsl动态拨号服务器?
- 七段显示器 + 74HC595 显示 / 设定
- 2017.9.16队内互测——老年组Day1
- GD32F303固件库开发
- VS开发Linux程序(VisualGDB)
- 今天终于玩了HiPiHi
- DIV+CSS的问题,DIV被挤到下面去了?如何解决?
- mysql 好用_mysql 好用的sql语句
- MyBatis Generator如何实现MYSQL分页插件