RxJS 操作符 scan 与 reduce 的区别

在 RxJS 中,scan 和 reduce 都是处理 Observable 数据流的操作符,它们可以用来逐步计算 Observable 的结果。但是,它们之间也有一些不同之处,本文将深入介绍和比较它们的区别。

reduce

reduce 操作符可以将 Observable 发射的数据流中的数据,按照自定义的函数进行聚合。具体来说,reduce 接收两个参数:

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

其中,accumulator 是一个函数,用来将每个 emitted 数据和之前的结果合并;seed 是一个可选的初始值,作为一个历史值。

我们可以通过一个简单的示例来看看 reduce 的使用:

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

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

在这个示例中,我们使用了 interval 创建了一个每秒发送一次的数据流,然后使用 reduce 这个操作符,将这些发射的数据逐步累加并输出。最终,我们会得到输出:0, 1, 3, 6, 10, 15, 21, ...,它们表示了从 0 开始,每秒累加一个数的结果。

从这个例子中我们可以看到,reduce 将过去所有的值存储在 accumulator 中,并在每个值发射时更新这个值。这就是 reduce 和 scan 的关键区别。

scan

scan 用法和 reduce 非常相似,它也是将 Observable 中的每个数据都与前面的结果一起聚合。但是它们有一个显著的不同:scan 会为每个聚合结果都发出一个新的 Observable。

和 reduce 一样,scan 也需要一个函数作为参数,用于每个发射值的聚合计算。这个函数的第一个参数是 accumulator,它表示当前的中间值。第二个参数是当前发射的值。和 reduce 不同的是,第一个值不是初始值而是 source observable 发射的第一个值。因此,和 reduce 相比,scan 可以得到每个中间值。

下面是一个示例:

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

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

在这个示例中,我们同样使用 interval 这个函数创建一个每秒发射一个数字的 Observable。使用 scan 订阅这个 Observable,并将每个数字逐步累加,并发出每个中间值。

输出结果为:0, 1, 3, 6, 10, 15, 21, ...,这个结果和我们使用 reduce 得到的结果完全一样。

但是,我们可以使用 scan 更多的功能。比如:

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

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

在这个示例中,Observable 发出了一个数组,使用 scan 对这个数组进行累加,最终发出所有中间结果的数组。输出结果:[], [1], [1, 2], [1, 2, 3], [1, 2, 3, 4]。

总结

无论是使用 reduce 还是 scan,对于一个 Observable 的聚合都是很方便的。reduce 与 scan 的不同之处在于,reduce 替换掉了中间值,只发出最后的结果,而 scan 则是为每一个中间值都发出一个结果。因此,一般来说,如果我们更关心每一次聚合的结果,使用 scan;如果我们只关心最后的结果,使用 reduce。

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


猜你喜欢

  • Custom Elements:如何为自定义元素添加样式?

    随着 Web 技术的不断发展,越来越多的开发者开始使用 Web Components 来构建 Web 应用。其中,Custom Elements 是 Web Components 的一个重要组成部分,...

    1 年前
  • 玩转 Express.js 的后台管理系统开发

    随着互联网的发展,后台管理系统已经成为了企业网站、电商平台、社交平台等网站的核心组成部分。在前端开发中,我们经常需要开发各种后台管理系统。Express.js 是一款流行的 Node.js 框架,它可...

    1 年前
  • ES12 中的 WeakRefs 对象

    在 ES12 中,JavaScript 引入了强大且令人兴奋的 WeakRefs 对象特性。该特性为前端开发者提供了一种垃圾回收动态跟踪的方法,并帮助开发人员在应用程序中避免一些常见的内存泄漏问题。

    1 年前
  • ESLint 报错: 'alert' is not defined

    ESLint 报错: 'alert' is not defined 在前端开发中,我们经常使用 alert 函数来弹出提示框,但是在使用 ESLint 进行代码规范检测时,会遇到 'alert' is...

    1 年前
  • Mocha 与 Chai 结合,构建 Node.js 单元测试

    Mocha 与 Chai 结合,构建 Node.js 单元测试 随着 JavaScript 语言的不断发展,前端开发已逐渐成为开发领域的重头戏,Node.js 的出现更是将 JavaScript 的应...

    1 年前
  • Material Design 中较优的表单设计方案及实现方式

    什么是 Material Design? Material Design 是由 Google 提出的一套设计语言,主要用于移动应用的设计。它的目的是为了在各个平台上,以一种层次清晰、流畅自然、物理感强...

    1 年前
  • Babel插件transform-runtime入门实践

    什么是Babel插件transform-runtime Babel是一个JavaScript编译器,能够将ES6及更高版本的JavaScript代码转换为向下兼容的代码,使得我们能够在支持ES6语法的...

    1 年前
  • ECMAScript 2019 (ES10) 对 BigInt 数据类型的支持和应用实例

    在 ECMAScript 2019 (ES10) 的发布中,BigInt 数据类型是一个重要的特性。BigInt 类型可以存储更大的整数,这种类型的数字可以用于需要更高的精度的运算,比如加密、密码学等...

    1 年前
  • Redis 中 ZSET(sorted set) 的使用方法

    在 Redis 中,ZSET 是一种有序集合,与 SET 相比,它可以给集合中的每个元素赋予一个分数(score),并根据分数对元素进行排序。因此,ZSET 在很多场景下都比 SET 更加实用,例如排...

    1 年前
  • 解决 Next.js favicon.ico 文件缺失问题

    在开发和部署 Next.js 应用时,经常会遇到 favicon.ico 文件缺失的问题。这个问题不仅会影响应用的美观度,还可能影响 SEO 和用户体验。本文将会详细讲解如何解决 Next.js fa...

    1 年前
  • MongoDB 在物联网(IoT)场景中的应用

    引言 物联网(IoT)日益成为互联网领域的新宠儿,也逐渐成为了各大企业争相进入的前沿领域。在物联网的应用场景下,大量数据的收集、存储和分析成为了必不可少的环节。而作为一款流行且强大的 NoSQL 数据...

    1 年前
  • Enzyme 测试 React 组件的同时引入 Mock 数据

    Enzyme 测试 React 组件的同时引入 Mock 数据 在前端开发中, React 组件是非常常见的一部分,它们主要负责 UI 展示和交互。要确保 React 组件的质量和准确性,在开发过程中...

    1 年前
  • Kubernetes 部署 MySQL,解决数据库集群问题

    随着互联网的发展,数据量越来越大,数据库集群成为日益重要的一部分。同时,由于前端与后端的分离,前端的技术栈也越来越固化,Kubernetes 作为容器编排的利器越来越受到前端工程师的青睐。

    1 年前
  • ES6 中的模板字符串和标签模板的应用

    在前端开发中,我们经常需要在字符串中插入变量或表达式,而在 ES5 中,通常我们会使用字符串拼接的方式来实现这一目的。但是随着 ES6 的到来,我们可以采用更加优雅的方式来处理这些需求,那就是使用模板...

    1 年前
  • Angular 中使用 ViewChild 来操作子组件

    在 Angular 中,通过 ViewChild 装饰器来引用子组件,可以让我们更方便地操作子组件,获取子组件的属性和方法,从而实现更为复杂的交互。 什么是 ViewChild? ViewChild ...

    1 年前
  • 使用 LESS 编写高效的 CSS 代码

    在前端开发中,我们经常需要编写 CSS 代码来美化和布局网页。然而,随着项目规模的不断扩大和复杂度的不断增加,CSS 代码变得越来越庞大和难以维护。这时候,我们就需要使用 LESS 这样的 CSS 预...

    1 年前
  • Mongoose 之如何使用 $limit 和 $skip 操作符进行分页

    在开发 Web 应用时,经常需要对大量数据进行分页展示。Mongoose 是 MongoDB 的对象数据建模工具,它提供了 $limit 和 $skip 操作符来支持分页查询。

    1 年前
  • 详解 ES11 中新增的 globalThis 对象及其使用场景

    ES11(也称为 ES2020)是 ECMAScript 核心规范的最新版本,它引入了许多新特性和语言改进,其中一个值得注意的新增对象是 globalThis。在本篇文章中,我们将探讨 globalT...

    1 年前
  • 解决 Deno 升级后代码运行出错的问题

    简介 Deno 是一个使用 Rust 编写的 JavaScript/TypeScript 运行时,由 Node.js 原创者 Ryan Dahl 开发。它可以直接运行 JavaScript/TypeS...

    1 年前
  • 手写 Promise 的流程

    本文将会介绍手写 Promise 的流程。Promise 是 JavaScript 中一种异步编程的解决方案。在异步操作中,使用回调函数来传递结果,但是回调函数嵌套过多,代码可读性较差。

    1 年前

相关推荐

    暂无文章