详解Angular2中的编程对象Observable


Posted in Javascript onSeptember 17, 2016

前言

RxJs提供的核心是Observable对象,它是一个使用可观察数据序列实现组合异步和事件编程。
跟这个很类似的异步编程模型是Promise,Promise是基于状态变化的异步模型,一旦由等待状态进入成功或失败状态便不能再次修改,当状态变化时订阅者只能够拿到一个值;而Observable是基于序列的异步编程模型,随着序列的变化,订阅者可以持续不断的获取新的值。而且Promise只提供回话机制,并没有更多的操作来支持对结果的复杂处理,而Observable提供了多种多样的操作符,来处理运算结果,以满足复杂的应用逻辑。

在实际编程中,我们主要与三个对象打交道:ObservableobserverSubscription

以一个元素的click事件为例看看如何使用Observable:

var clickStream = new Rx.Observable(observer => {
var handle = evt => observer.next(evt);
element.addEventListener('click', handle);

return () => element.removeEventListener('click', handle);
});

subscription = clickStream.subscribe(evt => {
console.log('onNext: ' + evt.id);
}, err => {
console.error('onError');
}, () => {
console.log('onComplete');
});

setTimeout(() => {
subscription.unsubscribe();
}, 1000);

如果每个事件都需要这么包装一下,岂不是太麻烦了,所以RxJs为我们提供了一个便利函数:Observable.fromEvent来方便的衔接事件。

常见的链接操作符:concat、merge、combineLates等

投影操作:map、flatMap,flatMap需要重点介绍

过滤:filter、distinctUltilChanges、

操作符分类:Operators by Categories

错误处理:catch、retry、finally

减压:debounce、throttle、sample、pausable

减少:buffer、bufferWithCount、bufferWithTime

想要掌握Observable的操作符先要学会看懂序列图:

详解Angular2中的编程对象Observable

箭头代表着随时间变化的序列,比如在一个元素上不断点击鼠标,圆圈代表序列对外产生的影响,如每一次点击元素都会触发一次事件回调,圆圈中的数字是对外发射的信息,如每一次事件的触发都会有一个事件对象,代表本次操作的一些信息。

想要灵活的运用Observable处理复杂的逻辑,就要学会使用它提供的操作符。我将操作符分为两类,单序列操作和复合序列操作,单序列操作是指的针对一个序列进行的操作运算,复合序列操作指的是对两个或者多个序列进行处理的操作符,复合序列操作相对更难懂一些。

下面先看单序列操作,以map操作为例:

详解Angular2中的编程对象Observable

map操作是将一个序列中每次对外发射的信息做转换,如上图map将每次的发射值乘以十,那么当订阅者订阅之后每次得到的订阅值就不再是原始的123而是经过转换后的10 20 30。通过序列图能更方便的理解Observable的运算。

下面我们来看一个复合序列操作,以merge为例

详解Angular2中的编程对象Observable

merge操作的目的是将两个独立序列,合成一个序列。原本序列1随着时间的前进,在100ms时发射a,在200ms时发射b,300ms时发射c,它的订阅者在400ms将受到abc三个值;序列2在150ms时发射d,250ms时发射e,350ms时发射f,它的订阅者在400ms内收到def三个值。而merge之后的新序列将在400ms内收到abcdef(注意顺序)。

常用操作符的理解:

Observable.range:发射一定数量值得序列。

Observable.toArray: 在序列完成时将所有发射值转换为一个数组。

Observable.flatMap: 将原始序列流中的元素转化为一个新的序列流,并将这个新的序列流merge到原来的序列中元素的位置。

Observable.startWith: 它会设置Observable序列的第一个值

Observable.combineLatest: 类似于promiseAll,在所有序列有结果后才会执行

Observable.scan: 将序列中每次发射的值可以做聚合,与reduce类似,reduce会将整个序列的值聚合起来,在序列完成时发送一个最终值

Observable.sample: 从持续的序列中取得一定的样品

Observable.merge:将多个序列合并成一个,可以做OR来使用

Observable.timestamp: 能够得到每个发射值的发射时的时间

Observable.distinctUntilChanged(compare, selector): selector取出用来比较的key,compare用来比较两个key

Observable.takeWhile() 当参数为false时停止发射数据

总结

以上就是这篇文章的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
利用JQuery+EasyDrag 实现弹出可拖动的Div,同时向Div传值,然后返回Div选中的值
Oct 24 Javascript
Jquery优化效率 提升性能解决方案
Sep 06 Javascript
基于jquery的文本框与autocomplete结合使用(asp.net+json)
May 30 Javascript
js与运算符和或运算符的妙用
Feb 14 Javascript
javascript为按钮注册回车事件(设置默认按钮)的方法
May 09 Javascript
jQuery实现鼠标点击弹出渐变层的方法
Jul 09 Javascript
JQuery移动页面开发之屏幕方向改变与滚屏的实现
Dec 03 Javascript
js图片切换具体实现代码
Oct 13 Javascript
浅谈JavaScript的函数及作用域
Dec 30 Javascript
使用 Node.js 模拟滑动拼图验证码操作的示例代码
Nov 02 Javascript
百度地图去掉marker覆盖物或者去掉maker的label文字方法
Jan 26 Javascript
vue实现移动端返回顶部
Oct 12 Javascript
详细总结Javascript中的焦点管理
Sep 17 #Javascript
js变量提升深入理解
Sep 16 #Javascript
再谈javascript常见错误及解决方法
Sep 16 #Javascript
使用JQuery中的trim()方法去掉前后空格
Sep 16 #Javascript
浅谈jQuery效果函数
Sep 16 #Javascript
jQuery插件easyUI实现通过JS显示Dialog的方法
Sep 16 #Javascript
jQuery实现的右下角广告窗体跟随效果示例
Sep 16 #Javascript
You might like
基于mysql的bbs设计(二)
2006/10/09 PHP
php中__toString()方法用法示例
2016/12/07 PHP
php中str_pad()函数用法分析
2017/03/28 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
JQuery Ajax 跨域访问的解决方案
2010/03/12 Javascript
appendChild() 或 insertBefore()使用与区别介绍
2013/10/11 Javascript
jquery ajax的success回调函数中实现按钮置灰倒计时
2013/11/19 Javascript
自定义的一个简单时尚js下拉选择框
2013/11/20 Javascript
JS将制定内容复制到剪切板示例代码
2014/02/11 Javascript
JS弹出层单纯的绝对定位居中示例代码
2014/02/18 Javascript
jQuery结合CSS制作漂亮的select下拉菜单
2015/05/03 Javascript
JavaScript中constructor()方法的使用简介
2015/06/05 Javascript
JavaScript函数中关于valueOf和toString的理解
2016/06/14 Javascript
Angularjs中$http以post请求通过消息体传递参数的实现方法
2016/08/05 Javascript
JS实战篇之收缩菜单表单布局
2016/12/10 Javascript
node.js调用Chrome浏览器打开链接地址的方法
2017/05/17 Javascript
微信小程序实现动态设置placeholder提示文字及按钮选中/取消状态的方法
2017/12/14 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
create-react-app构建项目慢的解决方法
2018/03/14 Javascript
微信小程序与公众号实现数据互通的方法
2019/07/25 Javascript
JavaScript 实现HTML DOM增删改查操作的常见方法详解
2020/01/04 Javascript
Vue proxyTable配置多个接口地址,解决跨域的问题
2020/09/11 Javascript
python正则表达式中的括号匹配问题
2014/12/14 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
2019/02/16 Python
PyCharm无法识别PyQt5的2种解决方法,ModuleNotFoundError: No module named 'pyqt5'
2020/02/17 Python
Python Sqlalchemy如何实现select for update
2020/10/12 Python
Python常用base64 md5 aes des crc32加密解密方法汇总
2020/11/06 Python
Ratchet 模态框的实现
2020/08/19 HTML / CSS
美国网上眼镜商城:Zenni Optical
2016/11/20 全球购物
小区门卫岗位职责
2013/12/31 职场文书
交通志愿者活动总结
2014/06/27 职场文书
2014年幼儿园教学工作总结
2014/12/04 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
甜美蛋糕店的创业计划书模板,拿来即用!
2019/08/21 职场文书
Python语言内置数据类型
2022/02/24 Python
一文弄懂MySQL索引创建原则
2022/02/28 MySQL