30 天精通 RxJS (05): 建立 Observable(一)
Observable 是 RxJS 的核心,今天让我们从如何建立 Observable 开始!
这是【30天精通 RxJS】的 05 篇,如果还没看过 04 篇可以往这边走:
[30 天精通 RxJS (04): 什么是 Observable ?]github.com/ShaofeiZi/3…
不想看文章的人,可以直接看视频喔!
今天大家看文章一定要分清楚 Observable 跟 Observer,不要搞混。
前几天我们把所有重要的观念及前置的知识都讲完了,今天要正式进入 RxJS 的应用,整个 RxJS 说白了就是一个核心三个重点。
一个核心是 Observable 再加上相关的 Operators(map, filter...),这个部份是最重要的,其他三个重点本质上也是围绕着这个核心在转,所以我们会花将近 20 天的篇数讲这个部份的观念及使用案例。
另外三个重点分别是
- Observer(观察者)
- Subject(订阅者)
- Schedulers(操作符)
Observer 是这三个当中一定会用到却是最简单的,所以我们今天就会把它介绍完。Subject 一般应用到的频率就相对低很多,但如果想要看懂 RxJS 相关的 Library 或 Framework,Subject 就是一定要会的重点,所以这个部份我们大概会花 3-5 天的时间讲解。至于 Schedulers 则是要解决 RxJS 衍伸出的最后一道问题,这个部份会视情况加入或是在 30 天后补完。
redux-observable 就是用了 Subject 实例的
让我卖个关子,先不说 RxJS 最后一道问题是什么。
说了这么多,我们赶快进入到今天的主题 Observable 吧!
建立 Observable: create
建立 Observable 的方法有非常多种,其中 create
是最基本的方法。create
方法在 Rx.Observable
事件中,要传入一个 callback function ,这个 callback function 会接收一个 observer 参数,如下
var observable = Rx.Observable.create(function(observer) {observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNextobserver.next('Anna');})复制代码
这个 callback function 会定义 observable 将会如何发送值。
虽然 Observable 可以被
create
,但实际上我们通常都使用 creation operator 像是 from, of, fromEvent, fromPromise 等。这里只是为了从基本的开始讲解所以才用create
我们可以订阅这个 observable,来接收他发送的值,代码如下
var observable = Rx.Observable.create(function(observer) {observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNextobserver.next('Anna');})// 订阅这个 observable
observable.subscribe(function(value) {console.log(value);
})复制代码
JSBin | JSFiddle
当我们订阅这个 observable,他就会依序发送 'Jerry'
'Anna'
两个字串。
订阅 Observable 跟 addEventListener 在实例上其实有非常大的不同。虽然在行为上很像,但实际上 Observable 根本没有管理一个订阅的清单,这个部份的细节我们留到最后说明!
这里有一个重点,很多人认为 RxJS 是在做非同步处理,所以所有行为都是非同步的。但其实这个观念是错的,RxJS 确实主要在处理非同步行为没错,但也同时能处理同步行为,像是上面的代码就是同步执行的。
证明如下
var observable = Rx.Observable.create(function(observer) {observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNextobserver.next('Anna');})console.log('start');
observable.subscribe(function(value) {console.log(value);
});
console.log('end');复制代码
JSBin | JSFiddle
上面这段代码会印出
start
Jerry
Anna
end复制代码
而不是
start
end
Jerry
Anna复制代码
所以很明显的这段代码是同步执行的,当然我们可以拿它来处理非同步的行为!
var observable = Rx.Observable.create(function(observer) {observer.next('Jerry'); // RxJS 4.x 以前的版本用 onNextobserver.next('Anna');setTimeout(() => {observer.next('RxJS 30 days!');}, 30)})console.log('start');
observable.subscribe(function(value) {console.log(value);
});
console.log('end');复制代码
JSBin | JSFiddle
这时就会印出
start
Jerry
Anna
end
RxJS 30 days!复制代码
从上述的代码能看得出来
Observable 同时可以处理同步与非同步的行为!
观察者 Observer
Observable 可以被订阅(subscribe),或说可以被观察,而订阅 Observable 的事件又称为 观察者(Observer)。观察者是一个具有三个方法(method)的事件,每当 Observable 发生事件时,便会呼叫观察者相对应的方法。
注意这里的观察者(Observer)跟上一篇讲的观察者模式(Observer Pattern)无关,观察者模式是一种设计模式,是思考问题的解决过程,而这里讲的观察者是一个被定义的事件。
观察者的三个方法(method):
next:每当 Observable 发发送新的值,next 方法就会被呼叫。
complete:在 Observable 没有其他的资料可以取得时,complete 方法就会被呼叫,在 complete 被呼叫之后,next 方法就不会再起作用。
error:每当 Observable 内发生错误时,error 方法就会被呼叫。
说了这么多,我们还是直接来建立一个观察者吧!
var observable = Rx.Observable.create(function(observer) {observer.next('Jerry');observer.next('Anna');observer.complete();observer.next('not work');})// 建立一个观察者,具备 next, error, complete 三个方法
var observer = {next: function(value) {console.log(value);},error: function(error) {console.log(error)},complete: function() {console.log('complete')}
}// 用我们定义好的观察者,来订阅这个 observable
observable.subscribe(observer)复制代码
JSBin | JSFiddle
上面这段代码会印出
Jerry
Anna
complete复制代码
上面的示例可以看得出来在 complete 执行后,next 就会自动失效,所以没有印出 not work
。
下面则是发送错误的示例
var observable = Rx.Observable.create(function(observer) {try {observer.next('Jerry');observer.next('Anna');throw 'some exception';} catch(e) {observer.error(e)}});// 建立一个观察者,具备 next, error, complete 三个方法
var observer = {next: function(value) {console.log(value);},error: function(error) {console.log('Error: ', error)},complete: function() {console.log('complete')}
}// 用我们定义好的观察者,来订阅这个 observable
observable.subscribe(observer)复制代码
JSBin | JSFiddle
这里就会执行 error 的 function 印出 Error: some exception
。
另外观察者可以是不完整的,他可以只具有一个 next 方法,如下
var observer = {next: function(value) {//...}
}复制代码
有时候 Observable 会是一个无限的序列,例如 click 事件,这时
complete
方法就有可能永远不会被呼叫!
我们也可以直接把 next, error, complete 三个 function 依序传入 observable.subscribe
,如下:
observable.subscribe(value => { console.log(value); },error => { console.log('Error: ', error); },() => { console.log('complete') }
)复制代码
observable.subscribe
会在内部自动组成 observer 事件来操作。
实例细节
我们前面提到了,其实 Observable 的订阅跟 addEventListener 在实例上有蛮大的差异,虽然他们的行为很像!
addEventListener 本质上就是 Observer Pattern 的实例,在内部会有一份订阅清单,像是我们昨天实例的 Producer
class Producer {constructor() {this.listeners = [];}addListener(listener) {if(typeof listener === 'function') {this.listeners.push(listener)} else {throw new Error('listener 必须是 function')}}removeListener(listener) {this.listeners.splice(this.listeners.indexOf(listener), 1)}notify(message) {this.listeners.forEach(listener => {listener(message);})}
}复制代码
我们在内部储存了一份所有的观察者清单(this.listeners
),在要发布通知时会对逐一的呼叫这份清单的观察者。
但在 Observable 不是这样实例的,在其内部并没有一份订阅者的清单。订阅 Observable 的行为比较像是执行一个事件的方法,并把资料传进这个方法中。
我们以下面的代码做说明
var observable = Rx.Observable.create(function (observer) {observer.next('Jerry');observer.next('Anna');})observable.subscribe({next: function(value) {console.log(value);},error: function(error) {console.log(error)},complete: function() {console.log('complete')}
})复制代码
像上面这段程式,他的行为比较像这样
function subscribe(observer) {observer.next('Jerry');observer.next('Anna');
}subscribe({next: function(value) {console.log(value);},error: function(error) {console.log(error)},complete: function() {console.log('complete')}
});复制代码
这里可以看到 subscribe 是一个 function,这个 function 执行时会传入观察者,而我们在这个 function 内部去执行观察者的方法。
订阅一个 Observable 就像是执行一个 function
今日小结
今天在讲关于建立 Observable 的实例,用到了 create
的方法,但大部分的内容还是在讲 Observable 几个重要的观念,如下
- Observable 可以同时处理同步跟非同步行为
- Observer 是一个事件,这个事件具有三个方法,分别是 next, error, complete
- 订阅一个 Observable 就像在执行一个 function
不知道读者是否有所收获,如果有任何问题或建议,欢迎在下方留言给我,谢谢。
30 天精通 RxJS (05): 建立 Observable(一)相关推荐
- # 30 天精通 RxJS (01):认识 RxJS
RxJS 是笔者认为未来几年内会非常红的 Library,RxJS 提供了一套完整的非同步解决方案,让我们在面对各种非同步行为,不管是 Event, AJAX, 还是 Animation 等,我们都可 ...
- 30 天精通 RxJS (03): Functional Programming 通用函数
了解 Functional Programming 的通用函数,能让我们写出更简洁的代码,也能帮助我们学习 RxJS. 这是[30天精通 RxJS]的 03 篇,如果还没看过 02 篇可以往这边走: ...
- 30 天精通 RxJS (01):认识 RxJS
原作者:一名來自台灣的小伙子,熱愛學習新技術,喜歡 JS 與 Functional Programming,熱衷於把困難的技術用簡單的語言闡述,歡迎來到我的文章. 原文 在网页中存取数据都是异步(As ...
- 你会用RxJS吗?【初识 RxJS中的Observable和Observer】
概念 RxJS是一个库,可以使用可观察队列来编写异步和基于事件的程序的库. RxJS 中管理和解决异步事件的几个关键点: Observable: 表示未来值或事件的可调用集合的概念. Observer ...
- ios7版 30天精通iPhone手机编程
更多精彩内容,请见:http://www.16boke.com 去年把<30天精通iPhone手机编程>这本书的例子做了一遍没有做笔记,今年用的ios7,并且是新版本的XCode,结合新的 ...
- 挑战30天精通Javaweb(IDEA版)!2021年最值得学习的JavaWeb教程
Javaweb教程,Javaweb入门教程,作为Java学习必须得一个类目,你能做到30天精通Javaweb吗?今天分享的这套Javaweb教程,就非常的全面,涵盖JavaWeb阶段所有核心知识点,最 ...
- PAT甲级1123 Is It a Complete AVL Tree (30分):[C++题解]建立平衡树、bfs,判完全二叉树
文章目录 题目分析 题目链接 题目分析 来源:pat网站 本题作为进阶题,它的基础知识点如下几题. PAT甲级1066 Root of AVL Tree (25分):[C++题解]建立平衡树(AVL树 ...
- Rxjs BehaviorSuject 和 Observable 的区别
https://stackoverflow.com/questions/39494058/behaviorsubject-vs-observable BehaviorSubject is a type ...
- 通过一个最简单的例子,理解Angular rxjs里的Observable对象的pipe方法
源代码: import { of } from 'rxjs'; import { Injectable } from '@angular/core'; import { map } from 'rxj ...
最新文章
- Druid 执行时间分布规则
- 用 Celery 实现邮件推送系统
- java播放声音和图片的代码_java怎么将出片处理成老照片?怎么播放声音?
- Arrays.asList()返回的ArrayList,这是Arrays里内嵌的一个私有静态类,而并不是java.util.ArrayList类
- oracle 表空间扩容方法
- iPhone 12系列详细屏幕参数前瞻:首批只有三星、LG屏幕 均为OLED面板
- malloc 源码_UE4源码剖析:MallocBinned(上)
- Android导入第三方类库
- 验证码计时 -- UIButton setTitle 闪烁问题解决方案
- 浏览器访问局域网共享文件服务器,局域网文件共享:Filezilla-IE 轻松解决(图)...
- war文件放到服务器乱码,maven 打war包tomcat服务器乱码问题
- MYSQL 索引 主键 外键
- Matlab中break语句
- dnf时装补丁教程_dnf时装补丁怎么用?DNF时装补丁教程
- html标签和css参数
- 微信小程序获取手机号码(仅前端部分
- 如何批量删除电脑上的空文件夹?
- html文字抖动效果,CSS实现TikTok文字抖动效果示例
- java公路车组装教程_自行车DIY入门教程,图文展示自行车组装全过程。(原创图文,转载请注明出处)...
- vue elementUI实现消息通知功能
热门文章
- python入门视频教程推荐-python入门学习哪个书比较好(python视频教程知乎)
- python 实现81个人脸关键点实时检测
- php7.2 的好处,PHP 7.2 中弃用的功能
- php 动态彩码辨色 接口的调用_好用的云函数!后端低代码接口开发,零基础编写API接口...
- 第二周数据采样过程及结果
- scrapy-redis组件写分布式爬虫实战
- 福大软工1816 · 第七次作业 - 需求分析报告之拖鞋旅游队
- Android扫描二维码 实现 登录网页
- 机器学习一 -- 什么是监督学习和无监督学习?
- 为什么有的人知道很多却一事无成?