RxJS系列01:响应式编程与异步

简介: RxJS系列01:响应式编程与异步

RxJS(Reactive Extensions for JavaScript) 是一个非常强大的 JS 库,我们可以使用它轻松编写异步代码。

在本系列文章中,我将带领你学习 RxJS 的最新版本,我们会重点关注如何使用响应式编程范式来解决你在日常工作中碰到的问题。所以这是一个偏实战的系列文章。

在本系列文章中,你将学会 RxJS 中的核心组件是如何使用和运作的。

通过学习这个系列文章,你将使用 RxJS 完成一个完整的项目开发,在这个项目中,你将了解如何处理 DOM 事件、如何构建响应式本地数据库等内容。


响应式编程介绍


要学习 RxJS,首先要了解什么是响应式编程,我在这里对它进行一个简短的介绍,包括为什么需要它以及如何使用它。

为什么需要响应式编程范式?


如今的应用程序非常复杂,开发人员必须采用一些编程范式来编写代码,这些范式可以提供一定程度的抽象,来帮助我们处理复杂的业务逻辑。

image.png

在如今,几乎每个 Web App 都会产生大量的实时交互数据。当 App 的某一个部分发生变化时,可能会触发另外一个完全不同的部分一起发生变化。我们可以将这种行为视作一个“事件”。正确的处理这些事件,以保证 UI 是正确渲染的,这就是响应式编程范式试图解决的问题。


什么是响应式编程范式?


响应式编程的主要目的是为我们的代码提供一定程度的抽象,可以让我们专注于业务逻辑生成的事件,而不是处理大量的实现细节。

在很多内容类网站上,都会有一个点赞按钮,当我们点击这个按钮的时候,会改改变按钮的颜色为高亮色,并且将点赞数量加一。这些所有的事件都会在不阻塞 UI 渲染的情况下发生,从而实现流畅的用户交互体验和满意度。这只是一个很简单的例子,如今的每个 Web App 都会包含很多种事件的生成和响应。这就是响应式编程的最佳定义:以相同的方式对不同的事件做出相应,并在此过程中植入业务逻辑。

响应式编程已经通过 Rx-Libraries 实现了可用于多种语言和平台的一系列库。在本系列文章中,我们将重点关注 JavaScript 的实现库:RxJS,并深入探讨这种凡事如何使我们能够以一种从未想过的方式解决问题。通过编写和响应式编程范式息息相关的函数式编程代码,你可以远离传统的命令式编程。

本系列文章中讨论的响应式概念是通用的,可以通过使用不同的 Rx 库在任何语言或者框架中编写响应式编程的代码。

在正式学习响应式编程之前,你需要初步了解和异步相关的几个概念和问题,以及了解响应式编程是如何解决这些问题的。


JavaScript 中的异步编程


要了解响应式编程可以解决哪些问题,你必须首先了解 JavaScript 中执行异步任务的不同方式及其缺点。有了这些知识,你就会觉得响应式编程是执行异步任务的最佳方式。

首先,JavaScript 是一门单线程的语言,这意味着所有的逻辑都可以在单个线程中执行,如果某个逻辑包含了一个耗时很长的操作,比如访问 I/O 和 HTTP 调用,那么其他逻辑在等待这些操作执行完成之前,整个页面的 UI 都将保持阻塞状态。为了解决这个问题,JavaScript 引入了异步编程的概念。而解决异步任务最早的方案是回调函数,后来解决方案变成了 Promise,再后来,也就是现在,解决方案变成了 async/await。接下来,我们要将解决方案变成响应式编程。但在这之前,我们需要先来了解这些概念以及它们的优缺点。


回调函数 callback


为了确保我们的逻辑在长耗时的任务运行结束立即执行,最简单的办法就是将将要执行的逻辑封装成回调函数,传递给长耗时任务。

下面是一个点击鼠标的例子:

javascript

复制代码

constcallbackFn = evt => console.log('你点击了鼠标')
document.addEventListener('mousedown', callbackFn)

它的缺点如下:

  1. 容易形成回调地狱,嵌套层级过多,难以管理代码。
  2. 很难包含回调之间的依赖关系,比如需要一个接一个的请求多个 HTTP 请求。


Promise


使用 Promise,我么你可以更轻松的使用回调函数。

Promise 可以简单的理解为一个容器或者代理,用于在未来的某个时刻可用的对象。当未来的对象可用的时候,将会调用一个回调函数。Promise 带来了几个好处。可以观察下面这个将文件上传到服务器的示例:


const uploadSuccessHandler = evt => console.log('上传成功')
const uploadFailedHandler = evt => console.log('上传失败')
uploadFile(file, uploadSuccessHandler, uploadFailedHandler)

上面这段代码是使用回调函数编写的。uploadFile 函数会通过 HTTP 请求将文件发送到服务器,如果成功上传,会调用 uploadSuccessHandler,失败则会调用 uploadFailedHandler。

如果 uploadFile 函数中以 throw 的方式抛出 Error,uploadFailedHandler 函数将无法执行。

如果使用 Promise 来重写,代码如下:


const uploadSuccessHandler = evt => console.log('上传成功')
const uploadFailedHandler = evt => console.log('上传失败')
uploadFile(file)
  .then(uploadSuccessHandler)
  .catch(uploadFailedHandler)

then 表示在异步操作异步操作成功后的回调,catch 表示异步操作失败后的回调。在 catch 中,即使是 throw 的 Error,一样可以捕获。

另外我们还可以通过链式调用的方式完成多个异步操作。代码如下所示:


uploadFile(file)
  .then(uploadSuccessHandler)
  .then(uploadUIHandler)
  .then(uploadEmailHandler)
  .catch(uploadFailedHandler)

除此之外,Promise 还可以同时运行多个异步任务。使用 Promise.all 可以等待这些任务全部完成,使用 Promise.race 可以等待其中任意一个完成。

即使有了这些功能,Promise 也不是一个解决不同问题的灵丹妙药。使用 Promise 最常见的缺点如下:

  1. Promise 只能处理产生一个值的数据源。当某个数据源产生了多个值,Promise 就无法处理了,比如我们监听鼠标事件。
  2. 如果我们想要取消某一个长耗时的任务,例如某一个 HTTP 请求,Promise 无法提供这种功能。

但是,这些缺点不应该是阻止我们使用 Promise 的理由。Promise 是轻量级的 API,我们可以轻松的将它应用于单值数据源的场景中,我们也可以将 Promise 和 RxJS 组合,用于更复杂的场景中。


相关文章
|
存储 缓存 JavaScript
深入浅出 RxJS 核心原理(响应式编程篇)
在最近的项目中,我们面临了一个需求:监听异步数据的更新,并及时通知相关的组件模块进行相应的处理。传统的事件监听和回调函数方式可能无法满足我们的需求,因此决定采用响应式编程的方法来解决这个问题。在实现过程中发现 RxJS 这个响应式编程库,可以很高效、可维护地实现数据的监听和组件通知。
354 0
深入浅出 RxJS 核心原理(响应式编程篇)
|
6月前
|
资源调度 JavaScript 前端开发
Redux异步解决方案 1. Redux-Thunk中间件
Redux异步解决方案 1. Redux-Thunk中间件
46 0
探秘 RxJS Observable 为什么要长成这个样子?!
我们都知道 RxJS Observable 最基础的使用方法:是建立 Observable,即调用 .create API
|
前端开发 JavaScript API
继续解惑,异步处理 —— RxJS Observable
Observable 可观察对象是开辟一个连续的通信通道给观察者 Observer,彼此之前形成一种关系,而这种关系需要由 Subscription 来确立,而在整个通道中允许对数据进行转换我们称为操作符 Operator。
|
机器学习/深度学习 存储 JavaScript
你就是函数响应式编程(FRP)啊?!【附 RxJS 实战】
什么是 FRP? 英文全称是:Functional Reactive Programming,翻译过来就是:函数响应式编程。
|
JavaScript 前端开发
三连弹!原生实现异步处理利器 —— Observable
本篇带来用原生实现 Observable,一探内部究竟!!
|
JavaScript 中间件
使用redux-thunk实现异步redux(基础文章)
使用redux-thunk实现异步redux(基础文章)
185 0
|
JSON JavaScript 前端开发
一起来看 rxjs
## 更新日志 - 2018-05-26 校正 - 2016-12-03 第一版翻译 ## 过去你错过的 Reactive Programming 的简介 你好奇于这名为Reactive Programming(反应式编程)的新事物, 更确切地说,你想了解它各种不同的实现(比如 [Rx*], [Bacon.js], RAC 以及其它各种各样的框架或库) 学习它比较困难, 因为
1162 0
|
JavaScript 前端开发 C++
rxjs简单入门
# rxjs简单入门 > rxjs全名Reactive Extensions for JavaScript,Javascript的响应式扩展, 响应式的思路是把随时间不断变化的数据、状态、事件等等转成可被观察的序列(Observable Sequence),然后订阅序列中那些Observable对象的变化,一旦变化,就会执行事先安排好的各种转换和操作 **rxjs适用于异步场景,即前端
34420 0