博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
# 30 天精通 RxJS (01):认识 RxJS
阅读量:6500 次
发布时间:2019-06-24

本文共 4352 字,大约阅读时间需要 14 分钟。

RxJS 是笔者认为未来几年内会非常红的 Library,RxJS 提供了一套完整的非同步解决方案,让我们在面对各种非同步行为,不管是 Event, AJAX, 还是 Animation 等,我们都可以使用相同的 API (Application Programming Interface) 做开发。

RxJS Logo

这是【30天精通 RxJS】的 01 篇,如果还没看过 00 篇可以往这边走:

在网页的世界存取任何资源都是非同步(Async)的,比如说我们希望拿到一个档案,要先发送一个请求,然后必须等到档案回来,再执行对这个档案的操作。这就是一个非同步的行为,而随着网页需求的复杂化,我们所写的 JavaScript 就有各种针对非同步行为的写法,例如使用 callback 或是 Promise 对象甚至是新的语法糖 async/await —— 但随着应用需求愈来愈复杂,撰写非同步的代码仍然非常困难。

非同步常见的问题

  • 竞态条件 (Race Condition)
  • 内存泄漏 (Memory Leak)
  • 复杂的状态 (Complex State)
  • 例外处理 (Exception Handling)

每当我们对同一个资源同时做多次的非同步存取时,就可能发生 Race Condition 的问题。比如说我们发了一个 Request 更新使用者资料,然后我们又立即发送另一个 Request 取得使用者资料,这时第一个 Request 和第二个 Request 先后顺序就会影响到最终接收到的结果不同,这就是 Race Condition。

Memory Leak 是最常被大家忽略的一点。原因是在传统网站的行为,我们每次换页都是整页重刷,并重新执行 JavaScript,所以不太需要理会内存的问题!但是当我们希望将网站做得像应用程式时,这件事就变得很重要。例如做 (Single Page Application) 网站时,我们是透过 JavaScript 来达到切换页面的内容,这时如果有对 DOM 注册监听事件,而没有在适当的时机点把监听的事件移除,就有可能造成 Memory Leak。比如说在 A 页面监听 body 的 scroll 事件,但页面切换时,没有把 scroll 的监听事件移除。

Complex State

当有非同步行为时,应用程式的状态就会变得非常复杂!比如说我们有一支付费用户才能播放的视频,首先可能要先抓取这部视频的资讯,接着我们要在播放时去验证使用者是否有权限播放,而使用者也有可能再按下播放后又立即按了取消,而这些都是非同步执行,这时就会各种复杂的状态需要处理。

Exception Handling

JavaScript 的 try/catch 可以捕捉同步的例外,但非同步的程式就没这么容易,尤其当我们的非同步行为很复杂时,这个问题就愈加明显。

各种不同的 API

我们除了要面对非同步会遇到的各种问题外,还需要烦恼很多不同的 API

  • DOM Events
  • XMLHttpRequest
  • fetch
  • WebSockets
  • Server Send Events
  • Service Worker
  • Node Stream
  • Timer

上面列的 API 都是非同步的,但他们都有各自的 API 及写法!如果我们使用 RxJS,上面所有的 API 都可以透过 RxJS 来处理,就能用同样的 API 操作 (RxJS 的 API)。

这里我们举一个例子,假如我们想要监听点击事件(click event),但点击一次之后不再监听。

原生 JavaScript

var handler = (e) => {    console.log(e);    document.body.removeEventListener('click', handler); // 结束监听}// 注册监听document.body.addEventListener('click', handler);复制代码

使用 Rx 大概的样子

Rx.Observable    .fromEvent(document.body, 'click') // 注册监听    .take(1) // 只取一次    .subscribe(console.log);复制代码

|

(点击画面后会在 console 显示,记得打开 console 来看)

大致上能看得出来我们在使用 RxJS 后,不管是针对 DOM Event 还是上面列的各种 API 我们都可以透过 RxJS 的 API 来做资料操作,像是示例中用 take(n) 来设定只取一次,之后就释放内存。

说了这么多,其实就是简单一句话

在面对日益复杂的问题,我们需要一个更好的解决方法。

RxJS 基本介绍

RxJS 是一套借由 Observable sequences 来组合非同步行为事件基础程序的 Library!

可以把 RxJS 想成处理 非同步行为 的 Lodash。

这也被称为 Functional Reactive Programming,更切确地说是指 Functional Programming 及 Reactive Programming 两个编程思想的结合。

RxJS 确实是 Functional Programming 跟 Reactive Programming 的结合,但能不能称为 Functional Reactive Programming (FRP) 一直有争议。

Rx 在上特别指出,有时这会被称为 FRP 但这其实是个“误称”。

简单说 FRP 是操作随着时间连续性改变的数值 而 Rx 则比较像是操作随着时间发出的离散数值,这个部份读者不用分得太细,因为 FRP 的定义及解释一直存在着歧异,也有众多大神为此争论,如下

:Rx 著名的推广者,也是 RxJS 5 主要贡献者之一,同时是 Cycle.js 的作者。Staltz 特别写了一篇解释为什么 Rx 不能说是 FRP 但他仍然称其为 FRP。

:曾在 Netflix 工作,目前任职于 Fitbit,经常出现在国外演讨会,主要写 Android。Juan Gomez 在 中特别提出他坚持称 Rx 为 FRP。

:任职于 NoRedInk,Elm 的作者。Evan 在 中,特别为现在各种 FRP 的不同解释做分类。

笔者自己的看法是比较偏向直接称 Rx 为 FRP,原因是这较为直觉(FP + RP = FRP),也比较不会对新手造成困惑,另外就是其他各种编程范式(包含 OOP, FP)其实都是想法的集合,而非严格的指南(Guideline),我们应该更宽松的看待 FRP 而不是给他一个严格的定义。

关于 Reactive Extension (Rx)

Rx 最早是由微软开发的 LinQ 扩展出来的开源专案,之后主要由社群的工程师贡献,有多种语言支援,也被许多科技公司所采用,如 Netflix, Trello, Github, Airbnb...等。

Rx 的相关资讯

  • 开源专案 (Apache 2.0 License)
  • 多种语言支持
    • JavaScript
    • Java
    • C#
    • Python
    • Ruby
    • ...(太多了列不完)
  • 微软目前最成功的开源专案

LinQ 唸做 Link,全名是 Language-Integrated Query,其功能很多元也非常强大;学 RxJS 可以不用会。

Functional Reactive Programming

Functional Reactive Programming 是一种编程范式(programming paradigm),白话就是一种写程式的方法论!举个例子,像 OOP 就是一种编程范式,OOP 告诉我们要使用对象的方式来思考问题,以及撰写程式。而 Functional Reactive Programming 其实涵盖了 Reactive Programming 及 Functional Programming 两种编程思想。

Functional Programming

Functional Programming 大部分的人应该多少都有接触过,这也是 Rx 学习过程中的重点之一,我们之后会花两天的篇幅来细讲 Functional Programming。

如果要用一句话来总结 Functional Programming,那就是 用 function 来思考我们的问题,以及撰写程式

在下一篇文章会更深入的讲解 Functional Programming

Reactive Programming

很多人一谈到 Reactive Programming 就会直接联想到是在讲 RxJS,但实际上 Reactive Programming 仍是一种编程范式,在不同的场景都有机会遇到,而非只存在于 RxJS,尤雨溪(Vue 的作者)就曾在 twitter 对此表达不满!

Evan You 的推文

Reactive Programming 简单来说就是 当变数或资源发生变动时,由变数或资源自动告诉我发生变动了

这句话看似简单,其实背后隐含两件事

  • 当发生变动 => 非同步:不知道什么时候会发生变动,反正变动时要跟我说
  • 由变数自动告知我 => 我不用写通知我的每一步代码

由于最近很红的 Vue.js 底层就是用 Reactive Programming 的概念实例,让我能很好的举例,让大家理解什么是 Reactive Programming!

当我们在使用 vue 开发时,只要一有绑定的变数发生改变,相关的变数及画面也会跟着变动,而开发者不需要写这其中如何通知发生变化的每一步代码,只需要专注在发生变化时要做什么事,这就是典型的 Reactive Programming (记得必须是由变数或资源主动告知!)

Vue.js 在做 two-ways data binding 是透过 ES5 definedProperty 的 getter/setter。每当变数发生变动时,就会执行 getter/setter 从而收集有改动的变数,这也被称为依赖收集

Rx 基本上就是上述的两个观念的结合,这个部份读者在看完之后的文章,会有更深的体悟。

今日小结

今天这篇文章主要是带大家了解为什么我们需要 RxJS,以及 RxJS 的基本介绍。若读者还不太能吸收本文的内容,可以过一段时间后再回来看这篇文章会有更深的体会,或是在下方留言给我!

转载地址:http://qktyo.baihongyu.com/

你可能感兴趣的文章
录音声音小
查看>>
Ubuntu 12.04 安装 Chrome浏览器
查看>>
java 反射
查看>>
ORACLE物化视图(物理视图)
查看>>
android 读取json数据(遍历JSONObject和JSONArray)(转)
查看>>
UIScrollView中的手势
查看>>
递归和迭代的差别
查看>>
基于jquery的可拖动div
查看>>
可以简易设置文字内边距的EdgeInsetsLabel
查看>>
[詹兴致矩阵论习题参考解答]习题1.3
查看>>
Android Fragment的使用
查看>>
沙朗javascript总结一下(一)---基础知识
查看>>
js深入研究之函数内的函数
查看>>
LeetCode:4_Median of Two Sorted Arrays | 求两个排序数组的中位数 | Hard
查看>>
python之commands模块
查看>>
android应用开发--------------看RadioGroup源代码,写相似单选选项卡的集成控件(如底部导航,tab等等)...
查看>>
LeetCode - Binary Tree Level Order Traversal
查看>>
FTP协议完全详解
查看>>
【C语言天天练(十五)】字符串输入函数fgets、gets和scanf
查看>>
【环境配置】配置sdk
查看>>