iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >RxJS有什么用
  • 337
分享到

RxJS有什么用

2024-04-02 19:04:59 337人浏览 独家记忆
摘要

这篇文章给大家分享的是有关Rxjs有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。RxJS简介通常,对RxJS的解释会是这么一些东西,我们来分

这篇文章给大家分享的是有关Rxjs有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

RxJS简介

通常,对RxJS的解释会是这么一些东西,我们来分别看看它们的含义是什么。

  • Reactive

  • Lodash for events

  • Observable

  • Stream-based

什么是Reactive呢,一个比较直观的对比是这样的:

比如说,abc三个变量之间存在加法关系:

a = b + c

在传统方式下,这是一种一次性的赋值过程,调用一次就结束了,后面b和c再改变,a也不会变了。

而在Reactive的理念中,我们定义的不是一次性赋值过程,而是可重复的赋值过程,或者说是变量之间的关系:

a: = b + c

定义出这种关系之后,每次b或者c产生改变,这个表达式都会被重新计算。不同的库或者语言的实现机制可能不同,写法也不完全一样,但理念是相通的,都是描述出数据之间的联动关系。

前端,我们通常有这么一些方式来处理异步的东西:

  • 回调

  • 事件

  • Promise

  • Generator

其中,存在两种处理问题的方式,因为需求也是两种:

  • 分发

  • 流程

在处理分发的需求的时候,回调、事件或者类似订阅发布这种模式是比较合适的;而在处理流程性质的需求时,Promise和Generator比较合适。

在前端,尤其交互很复杂的系统中,RxJS其实是要比Generator有优势的,因为常见的每种客户端开发都是基于事件编程的,对于事件的处理会非常多,而一旦系统中大量出现一个事件要修改视图的多个部分(状态树的多个位置),分发关系就更多了。

RxJS的优势在于结合了两种模式,它的每个Observable上都能够订阅,而Observable之间的关系,则能够体现流程(注意,RxJS里面的流程的控制和处理,其直观性略强于Promise,但弱于Generator)。

我们可以把一切输入都当做数据流来处理,比如说:

  • 用户操作

  • 网络响应

  • 定时器

  • Worker

RxJS提供了各种api来创建数据流:

  • 单值:of, empty, never

  • 多值:from

  • 定时:interval, timer

  • 从事件创建:fromEvent

  • 从Promise创建:fromPromise

  • 自定义创建:create

创建出来的数据流是一种可观察的序列,可以被订阅,也可以被用来做一些转换操作,比如:

  • 改变数据形态:map, mapTo, pluck

  • 过滤一些值:filter, skip, first, last, take

  • 时间轴上的操作:delay, timeout, throttle, debounce, audit, bufferTime

  • 累加:reduce, scan

  • 异常处理:throw, catch, retry, finally

  • 条件执行:takeUntil, delayWhen, retryWhen, subscribeOn, ObserveOn

  • 转接:switch

也可以对若干个数据流进行组合:

  • concat,保持原来的序列顺序连接两个数据流

  • merge,合并序列

  • race,预设条件为其中一个数据流完成

  • forkJoin,预设条件为所有数据流都完成

  • zip,取各来源数据流最后一个值合并为对象

  • combineLatest,取各来源数据流最后一个值合并为数组

这时候回头看,其实RxJS在事件处理的路上已经走得太远了,从事件到流,它被称为lodash for events,倒不如说是lodash for stream更贴切,它提供的这些操作符也确实可以跟lodash媲美。

数据流这个词,很多时候,是从data-flow翻译过来的,但flow跟stream是不一样的,我的理解是:flow只关注一个大致方向,而stream是受到更严格约束的,它更像是在无形的管道里面流动。

那么,数据的管道是什么形状的?

在RxJS中,存在这么几种东西:

  • Observable 可观察序列,只出不进

  • Observer 观察者,只进不出

  • Subject 可出可进的可观察序列,可作为观察者

  • ReplaySubject 带回放

  • Subscription 订阅关系

前三种东西,根据它们数据进出的可能性,可以通俗地理解他们的连接方式,这也就是所谓管道的“形状”,一端密闭一端开头,还是两端开口,都可以用来辅助记忆。

上面提到的Subscription,则是订阅之后形成的一个订阅关系,可以用于取消订阅。

下面,我们通过一些示例来大致了解一下RxJS所提供的能力,以及用它进行开发所需要的思路转换。

示例一:简单的订阅

很多时候,我们会有一些显示时间的场景,比如在页面下添加评论,评论列表中显示了它们分别是什么时间创建的,为了含义更清晰,可能我们会引入moment这样的库,把这个时间转换为与当前时间的距离:

const diff = moment(createAt).fromNow()

这样,显示的时间就是:一分钟内,昨天,上个月这样的字样。

但我们注意到,引入这个转换是为了增强体验,而如果某个用户停留在当前视图时间太长,它的这些信息会变得不准确,比如说,用户停留了一个小时,而它看到的信息还显示:5分钟之前发表了评论,实际时间是一个小时零5分钟以前的事了。

从这个角度看,我们做这个体验增强的事情只做了一半,不准确的信息是不能算作增强体验的。

在没有RxJS的情况下,我们可能会通过一个定时器来做这件事,比如在组件内部:

tick() {
this.diff = moment(createAt).fromNow()
setTimeout(tick.bind(this), 1000)
}

但组件并不一定只有一份实例,这样,整个界面上可能就有很多定时器在同时跑,这是一种浪费。如果要做优化,可以把定时器做成一种服务,把业务上需要周期执行的东西放进去,当作定时任务来跑。

如果使用RxJS,可以很容易做到这件事:

Observable.interval(1000).subscribe(() => {
this.diff = moment(createAt).fromNow()
})

示例二:对时间轴的操纵

RxJS一个很强大的特点是,它以流的方式来对待数据,因此,可以用一些操作符对整个流上所有的数据进行延时、取样、调整密集度等等。

const timeA$ = Observable.interval(1000)
const timeB$ = timeA$.filter(num => {
return (num % 2 != 0)
&& (num % 3 != 0)
&& (num % 5 != 0)
&& (num % 7 != 0)
})
const timeC$ = timeB$.debounceTime(3000)
const timeD$ = timeC$.delay(2000)

示例代码中,我们创建了四个流:

  • A是由定时器产生的,每秒一个值

  • B从A里面过滤掉了一些

  • C在B的基础上,对每两个间距在3秒之内的值进行了处理,只留下后一个值

  • D把C的结果整体向后平移了2秒

所以结果大致如下:

A: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
B:    1                                 11       13                  17       19
C:          1                                                  13                             19
D:                 1                                                      13

示例三:我们来晚了

RxJS还提供了BehaviourSubject和ReplaySubject这样的东西,用于记录数据流上一些比较重要的信息,让那些“我们来晚了”的订阅者们回放之前错过的一切。

ReplaySubject可以指定保留的值的个数,超过的部分会被丢弃。

最近新版《射雕英雄传》比较火,我们来用代码描述其中一个场景。

郭靖和黄蓉一起背书,黄蓉记忆力很好,看了什么,就全部记得;而郭靖属鱼的,记忆只有七秒,始终只记得背诵的最后三个字,两人一起背诵《九阴真经》。

代码实现如下:

const 九阴真经 = '天之道,损有余而补不足'
const 黄蓉$ = new ReplaySubject(Number.MAX_VALUE)
const 郭靖$ = new ReplaySubject(3)
const 读书$ = Observable.from(九阴真经.split(''))
读书$.subscribe(黄蓉$)
读书$.subscribe(郭靖$)

执行之后,我们就可以看到,黄蓉背出了所有字,郭靖只记得“补不足”三个字。

示例四:自动更新的状态树

熟悉Redux的人应该会对这样一套理念不陌生:

当前视图状态 := 之前的状态 + 本次修改的部分

从一个应用启动之后,整个全局状态的变化,就等于初始的状态叠加了之后所有action导致的状态修改结果。

所以这就是一个典型的reduce操作。在RxJS里面,有一个scan操作符可以用来表达这个含义,比如说,我们可以表达这样一个东西:

const action$ = new Subject()
const reducer = (state, payload) => {
// 把payload叠加到state上返回
}
const state$ = action$.scan(reducer)
.startWith({})

只需往这个action$里面推action,就能够在state$上获取出当前状态。

在Redux里面,会有一个东西叫combineReducer,在state比较大的时候,用不同的reducer修改state的不同的分支,然后合并。如果使用RxJS,也可以很容易表达出来:

const meAction$ = new Subject()
const meReducer = (state, payload) => {}
const articleAction$ = new Subject()
const articleReducer = (state, payload) => {}
const me$ = meAction$.scan(meReducer).startWith({})
const article$ = articleAction$.scan(articleReducer).startWith({})
const state$ = Observable
.zip(
me$,
article$,
(me, article) => {me, article}
)

借助这样的机制,我们实现了Redux类似的功能,社区里面也有基于RxJS实现的Redux-Observable这样的Redux中间件

注意,我们这里的代码中,并未使用dispatch action这样的方式去严格模拟Redux。

再深入考虑,在比较复杂的场景下,reducer其实很复杂。比如说,视图上发起一个操作,会需要修改视图的好多地方,因此也就是要修改全局状态树的不同位置。

在这样的场景中,从视图发起的某个action,要么调用一个很复杂的reducer去到处改数据,要么再次发起多个action,让很多个reducer各自改自己的数据。

前者的问题是,代码耦合太严重;后者的问题是,整个流程太难追踪,比如说,某一块状态,想要追踪到自己是被从哪里发起的修改所改变的,是非常困难的事情。

如果我们能够把Observable上面的同步修改过程视为reducer,就可以从另外一些角度大幅简化代码,并且让联动逻辑清晰化。例如,如果我们想描述一篇文章的编辑权限:

const editable$ = Observable.combineLatest(article$, me$)
.map(arr => {
let [article, me] = arr
return me.isAdmin || article.author === me.id
})

这段代码的实质是什么?其实本质上还是reducer,表达的是数据的合并与转换过程,而且是同步的。我们可以把article和me的变更reduce到article$和me$里,由它们派发隐式的action去推动editable计算新值。

感谢各位的阅读!关于“RxJS有什么用”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

--结束END--

本文标题: RxJS有什么用

本文链接: https://www.lsjlt.com/news/78156.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • RxJS有什么用
    这篇文章给大家分享的是有关RxJS有什么用的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。RxJS简介通常,对RxJS的解释会是这么一些东西,我们来分...
    99+
    2024-04-02
  • rxjs和react有什么区别
    今天小编给大家分享一下rxjs和react有什么区别的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2024-04-02
  • RxJS中Subject怎么用
    这篇文章将为大家详细讲解有关RxJS中Subject怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Observer Pattern观察者模式定义观察者模式又叫发布订...
    99+
    2024-04-02
  • JavaScript中rxjs与Observable操作符怎么使用
    这篇文章主要讲解了“JavaScript中rxjs与Observable操作符怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript中rxjs与Observable操作符...
    99+
    2023-07-02
  • Rxjs监听精确使用版本上线
    目录导语思路注释掉一个触发条件...解构是2次,是不是这里导致的?那就是监听的地方,触发了2遍拓展:You provided an invalid object解决办法总结导语 最近...
    99+
    2022-11-13
    Rxjs监听版本上线 Rxjs监听
  • Angular中RxJS怎么映射数据
    小编给大家分享一下Angular中RxJS怎么映射数据,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧! ...
    99+
    2024-04-02
  • React中如何使用RxJS优化数据流
    这篇文章主要介绍了React中如何使用RxJS优化数据流的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇React中如何使用RxJS优化数据流文章都会有所收获,下面我们一起来看看吧。一般来说,处理组件中的数据流无...
    99+
    2023-07-05
  • 如何使用angular的HttpClient搭配rxjs
    小编给大家分享一下如何使用angular的HttpClient搭配rxjs,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、原H...
    99+
    2024-04-02
  • Angular5升级RxJS到5.5.3报错怎么办
    这篇文章给大家分享的是有关Angular5升级RxJS到5.5.3报错怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。RxJS是一种针对异步数据流编程工具,或者叫响应式扩展编...
    99+
    2024-04-02
  • Angular中的可观察对象、观察者和RxJS操作符是什么
    这篇文章主要介绍“Angular中的可观察对象、观察者和RxJS操作符是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Angular中的可观察对象、观察者和Rx...
    99+
    2024-04-02
  • React 中使用 RxJS 优化数据流的处理方案
    目录正文一般来说,处理组件中的数据流无非三种情况:下面我们看一个很简单的例子:那么,问题来了,使用数据流的方式来处理数据有什么好处呢?正文 现在我们比较熟悉的是使用 functio...
    99+
    2023-02-17
    React RxJS 优化数据流 React RxJS
  • angular.js4如何使用RxJS处理多个Http请求
    这篇文章将为大家详细讲解有关angular.js4如何使用RxJS处理多个Http请求,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。有时候进入某个页面时,我们需要从多个 ...
    99+
    2024-04-02
  • Angular搜索场景中如何使用rxjs的操作符处理
    这篇文章主要为大家展示了“Angular搜索场景中如何使用rxjs的操作符处理”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Angular搜索场景中如何使用rx...
    99+
    2024-04-02
  • css是什么?有什么用?
    CSS,即层叠样式表(Cascading Style Sheets),是一种用于网页设计的样式语言。通过CSS,你可以改变HTML页面上各个元素的外观、布局和行为。CSS最初是由赛迪公司(斯佩克特公司)的开发者创建的,并于1996年成为一项...
    99+
    2023-05-14
  • verdaccion有什么用
    这篇文章将为大家详细讲解有关verdaccion有什么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。Verdaccio 是什么Verdaccio 是一个简单的零配置的node.js轻量私有的npm代理仓...
    99+
    2023-06-04
  • SQL有什么用
    小编给大家分享一下SQL有什么用,希望大家阅读完这篇文章后大所收获,下面让我们一起去探讨吧!Sql(STructured Query Language)是管理数据库所有操作的通用语言,是一种资料库查询和程式...
    99+
    2024-04-02
  • InnoDB有什么用
    小编给大家分享一下InnoDB有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!InnoDB是一个通用的高性能、高可靠性的存...
    99+
    2024-04-02
  • SQLite有什么用
    这篇文章主要介绍SQLite有什么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!什么是SQLiteSQLite是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个...
    99+
    2024-04-02
  • Require.js有什么用
    小编给大家分享一下Require.js有什么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一:什么是require.js①:r...
    99+
    2024-04-02
  • Vue.js有什么用
    这篇文章主要介绍Vue.js有什么用,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!首先,咋们要学习一个js框架,那么肯定要引入该框架的基础库,这里我创建一个页面并且引用官网的库是:&...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作