RxJS 中的冷 / 热 Observable 问题及解决方案

面试官:小伙子,你的数组去重方式惊艳到我了

RxJS 是一个流行的 JavaScript 库,用于响应式编程。它提供了处理异步事件流的方式,并可用于前端开发的各种问题解决方案中。在使用 RxJS 时,了解冷 Observable 和热 Observable 的差异是非常重要的,因为它们在处理流时有很大的不同。

什么是 Observable?

Observable 是 RxJS 中的一个对象,它表示异步事件流的概念。事件流可以是来自任何源的数据,例如用户交互、网络请求和计时器。Observable 实例是可被订阅的,因此当事件发生时,可以通过 Observer 来执行某些操作。

Observer

Observer 是一个对象,它定义了如何响应 Observable 发出的值。当 Observable 触发事件时,Observer 可以执行一些功能,例如将事件打印到控制台,显示动画或更改 DOM 中的元素。

Observer 必须实现三个方法:

  • next(value) - 当 Observable 发出一个值时,会调用此方法。
  • error(err) - 当 Observable 发生错误时,可以通过此方法处理该错误。
  • complete() - 当 Observable 完成时,该方法被调用。

冷 Observable

冷 Observable 是最容易理解的一种,当你订阅它时,Observable 会为每个 Subscriber 重新执行一遍。因此,对于每个新的订阅者,Observable 都会重新执行并生成事件流。这就是“冷”的含义,因为它为每个订阅者提供了一个新的事件流。

例如,下面的代码中,我们创建一个简单的冷 Observable:

------ - ---------- - ---- -------

----- ---------- - --- --------------------- -- -
  ----------------------- -- ---------------

  -----------------
  -----------------
  -----------------
---

---------------------------- -- ----------------------- -- ------------
---------------------------- -- ----------------------- -- ------------

这会输出:

---------- -- ------------
---------- -- -
---------- -- -
---------- -- -
---------- -- ------------
---------- -- -
---------- -- -
---------- -- -

这表明了,对于每个订阅者,Observable 都重新执行并生成一个新的事件流。

热 Observable

热 Observable 区别于冷 Observable 的最大不同点是,它会在 Observable 创建后立即开始发出事件,即无论是否有已订阅的观察者。这就是“热”观察者的含义,因为它始终发出同一个事件流。

例如,下面的代码中,我们创建了一个热 Observable:

------ - --------- - ---- -------

----- ----- - ------------------------ ---------

------------------ -- ----------------------- - ------------
------------- -- -
  ------------------ -- ----------------------- - ------------
-- ------

此代码会在页面中的任何位置监听用户单击事件。如果用户在两秒内单击两次,那么两个不同的订阅者都将获得该事件,因为该事件流已经存在并且正在发出通知。

解决方案:主题和 ReplaySubject

如果你希望通过订阅一个 Observable,仅能获取数据的最新更新(而不是发出的每个更新),那么你需要使用 RxJS 中的 Subject。

主题(Subject)

Subject 可以像 Observable 一样发出值,并且还可以通过 next() 方法将新值传递给已订阅的观察者。Subject 还充当观察者和被观察者之间的桥梁,也就是说,它既可以订阅 Observable,还可以被其他观察者订阅。

Subject 有两种类型:普通(或非广播)和广播。我们可以使用普通主题来解决热观察者的问题。普通主题在创建时不会发出任何值,而只有在绑定的 Subscriber 收到任何值时才会发出它们。这种方式可以确保每个订阅者获取到有用的更新,但是,如果订阅普通主题的其他 Subscriber 发生在最新更新之前,订阅者将无法获得该更新。

例如:

------ - ------- - ---- -------

----- ------- - --- ----------

----------------
------------------------- -- ----------------------- -- ------------
----------------
----------------
------------------------- -- ----------------------- -- ------------
----------------

输出:

---------- -- -
---------- -- -
---------- -- -
---------- -- -
---------- -- -

ReplaySubject

ReplaySubject 是一种可重播的 Subject,在订阅之前会记录 Observable 发出的最新 n 个项,并在订阅后将这些项发出。这使您可以在订阅 Replaysubject 的新 Subscriber 时,让它们接收到最新和以前的所有更新。例如:

------ - ------------- - ---- -------

----- ------- - --- -----------------

----------------
----------------
----------------
------------------------- -- ----------------------- -- ------------
----------------
------------------------- -- ----------------------- -- ------------
----------------

输出:

---------- -- -
---------- -- -
---------- -- -
---------- -- -
---------- -- -
---------- -- -
---------- -- -

在上面的示例中,我们创建了一个新的 ReplaySubject,它保存最新的两个值。我们首先将值 1、2 和 3 发送到 ReplaySubject 中。然后,我们订阅了 ReplaySubject,这会向订阅者 A 发出最新的两个值(即 2 和 3)。接下来,我们发送了值 4,并订阅了 ReplaySubject,这会要求订阅者 B 获取最新的两个值,这是值 3 和 4。最后,我们发送值 5,并将其发送给两个订阅者。这是主题的适当的行为形式,因为每个 Subscriber 都会获得相同的值。

结论

熟悉 RxJS 中的冷 / 热 Observable 差异以及如何解决这些差异的问题,可以帮助您更好地处理异步事件流,编写更高效的代码以及提高代码可读性。概括而言,使用普通主题或 ReplaySubject 通过订阅 Observable 来确保每个新订阅者都能获取到有用的更新,并且能够获得最新的值。如果您需要更精细的控制,则可以从热 Observable 转移到 Subject 或 ConnectableObservable。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/6707cd7ed91dce0dc86c9c91


猜你喜欢

  • 浅谈构建 React.js 的 SPA 应用程序时的最佳实践

    React.js 已经成为了现代前端框架中最流行的之一,主要因为其卓越的性能和强大的功能,所以构建 SPA 应用程序时使用 React.js 是非常值得推荐的,但要想维护一份高质量的代码并非易事。

    9 天前
  • 避免 CSS Reset 引起的外边距无效问题

    什么是 CSS Reset? CSS Reset 是一种常用的前端技术,用于消除浏览器默认样式,使网页的外观更加统一和可控。它通常是一段包含一系列 CSS 属性的代码片段,可将 HTML 元素的样式设...

    9 天前
  • 在响应式设计中如何使用滚动效果来增强用户体验

    响应式设计已经成为了现代 Web 设计的标配,它可以让网站在不同大小的屏幕上呈现出最佳的排版效果。但是,响应式设计本身并不能确保用户体验良好,而在页面中添加滚动效果则是提高用户体验的常用方法之一。

    9 天前
  • 使用 Next.js 构建在线图书馆的最佳实践

    在这个数字时代,人们更倾向于使用网络获取信息和娱乐。因此,构建一个在线图书馆是有意义的,它可以为人们提供方便,同时也可以成为一个很好的学习项目。在本文中,我将介绍如何使用 Next.js 构建在线图书...

    9 天前
  • 构建基于 Webpack 的前后端应用

    随着前端技术的不断发展,前端开发不再仅仅局限于设计布局和交互体验,越来越多的复杂业务逻辑也被前端承担,这也导致了前端应用变得越来越庞大、复杂,开发、部署和维护等方面也面临越来越多的挑战。

    9 天前
  • PWA 开发中应用动态加载的实现方法

    为了提高 PWA 应用的性能和用户体验,开发者需要采用动态加载的方式,来减轻应用加载时间和启动时间的负担。本文将介绍 PWA 应用动态加载的方法,包括代码分割、懒加载和预加载等方法。

    9 天前
  • 在Vue.js中如何使用axios进行数据请求

    前言 在现代Web应用中,数据请求是非常常见的操作。Vue.js是一种流行的JavaScript框架,可以帮助我们构建可维护和易扩展的Web应用。axios是一个很棒的HTTP客户端库,可以帮助我们在...

    9 天前
  • 学习 ES11:ECMAScript 2020 新特性全解析

    ECMAScript 是一种用于编写网页脚本语言的标准化语言,而 ES11 则是它的最新版本,也被称为 ES2020。ES11 引入了一系列新的特性,包括可选链操作符,动态导入, BigInt 数据类...

    9 天前
  • Mongoose 中如何实现使用 GraphQL 进行查询和变更?

    GraphQL 是一种 API 查询语言和运行时环境,用于查询 API 的数据。而 Mongoose 是一个在 Node.js 中操作 MongoDB 数据库的工具,通过编写 Schema 然后创建 ...

    9 天前
  • 如何在自定义元素中使用 CSS 预处理器

    随着前端技术的不断发展,我们已经习惯了使用 CSS 预处理器来简化样式表的编写和维护。然而,如果我们想在自定义元素中使用 CSS 预处理器,就需要额外的一些步骤。 在本文中,我们将以 Sass 为例介...

    9 天前
  • 如何使用 GraphQL 构建灵活和可扩展的 API

    GraphQL 是一种新兴的 API 技术,它提供了一种灵活和可扩展的方式来构建 API。相比传统的 RESTful API,GraphQL 具有更好的数据获取和管理功能,可以大大提高前端开发效率和用...

    9 天前
  • TypeScript 中实现 Server-Sent Events(SSE)开发实践

    前言 Server-Sent Events(SSE)是一种用于服务器向客户端发送流式数据的技术,该技术可以自动重连,非常适合实时通知和聊天等场景。本文将介绍如何使用 TypeScript 实现 SSE...

    9 天前
  • ES9 中 Async 函数的错误处理方法详解

    在前端开发中,异步编程是非常常见的。通常使用 Promise、async/await 等方法进行异步编程。而在 ES9 中,Async 函数也得到了增强,其中的错误处理方法也有了改进,使得异步编程更加...

    9 天前
  • 如何理解 Vue.js 的单页应用程序(SPA)?

    Vue.js 是一种流行的 JavaScript 框架,可用于构建单页应用程序(SPA)。单页应用程序是一种 Web 应用程序,其中只有一个 HTML 页面,但可以动态更新该页面的不同部分,从而提高应...

    9 天前
  • 如何使用 ES8 中引入的 Promise.prototype.finally() 方法来正确处理异常

    随着 JavaScript 的发展,Promise 已经成为了处理异步操作的标准方式。但是处理异常一直是 Promise 处理中的难点之一。在 ES8 中,引入了 Promise.prototype....

    9 天前
  • 在 Angular 中正确使用 RxJS 的 tap 操作符

    RxJS 是一个流行的 JavaScript 库,它提供了强大的 Observable 和操作符,使得异步编程变得更加容易。Angular 使用了 RxJS 来实现一些常见的模式,例如异步调用 HTT...

    9 天前
  • 如何通过边框颜色提升无障碍性能

    随着互联网的不断发展,更多的人开始依赖互联网进行日常生活和工作,而其中有许多用户是通过辅助技术使用互联网,这些技术包括屏幕阅读器、放大镜等,这些用户需要更好的无障碍性能来确保他们的使用体验。

    9 天前
  • 如何将 ES6 转换为 ES5 并使用 Babel Polyfill

    随着前端技术的发展,越来越多的开发者开始使用 ES6(也称为 ES2015)来编写 JavaScript 代码。ES6为开发者提供了许多便捷且强大的功能,如箭头函数、模板字符串、类等等。

    9 天前
  • 在 Jest 中测试 React-Native 组件

    React-Native 是一种流行的跨平台移动开发框架。而 Jest 是一种用于 JavaScript 应用程序测试的流行测试框架。在前端开发中,测试组件是至关重要的一环。

    9 天前
  • MongoDB 聚合分析的实现原理介绍

    前言 MongoDB 是一个非关系型数据库,如今在 web 开发中使用越来越广泛。因为它具有的高效率、可扩展性和灵活性。其中的聚合分析功能让 MongoDB 在数据操作方面表现出色。

    9 天前

相关推荐

    暂无文章