0

0

深入理解 RxJS first 操作符:区分值发射模式

DDD

DDD

发布时间:2025-10-23 10:06:15

|

670人浏览过

|

来源于php中文网

原创

深入理解 rxjs first 操作符:区分值发射模式

RxJS 的 `first` 操作符用于获取 Observable 发射的第一个值。其行为差异主要取决于 Observable 如何发射数据:是作为一个整体的数组值,还是将数组元素逐个扁平化发射。理解 `of()` 与 `from()` 等创建操作符的区别,以及如何利用 `mergeAll()` 等操作符进行扁平化处理,是正确使用 `first` 的关键,避免对数组内容产生误解。

RxJS first 操作符基础

first 操作符的本质是获取源 Observable 产生的第一个值。它可以不带参数,直接返回第一个发射的值;也可以接受一个谓词函数,返回第一个满足该谓词条件的值。一旦找到并返回了相应的值,first 操作符就会完成源 Observable 的订阅,并发出 complete 通知。

例如,一个简单的 Observable 序列 1, 2, 3,first() 会返回 1。如果序列是 [1, 2, 3], [4, 5, 6],first() 将返回 [1, 2, 3]。理解其核心在于“发射的值”是一个整体。

核心概念:何为“发射值”?

first 操作符的关键在于它作用于 Observable 实际发射的每一个值。一个常见的误解是,当 Observable 发射一个数组时,first 会自动“解包”这个数组并返回其内部的第一个元素。然而,这并非 first 的工作方式。

为了阐明这一点,我们来看两种不同的 Observable 值发射模式。

场景一:发射单个数组作为值

当一个 Observable 将整个数组作为一个单一事件发射时,first 操作符会把这个完整的数组视为其接收到的第一个“值”。

考虑以下代码示例:

import { Observable, of } from 'rxjs';
import { first } from 'rxjs/operators';

// 示例 1: 使用 new Observable 手动发射数组
new Observable<number[]>(s => {
  s.next([1, 2, 3, 4]); // 整个数组 [1,2,3,4] 被作为一个单一值发射
  s.complete();
})
.pipe(first())
.subscribe({
  next: (response) => console.log('示例 1 结果:', response) // 输出: [1,2,3,4]
});

// 示例 2: 使用 of 操作符发射数组
of([5, 6, 7, 8]) // of 操作符将 [5,6,7,8] 作为一个单一值发射
.pipe(first())
.subscribe({
  next: (response) => console.log('示例 2 结果:', response) // 输出: [5,6,7,8]
});

在这两个示例中,Observable 并没有发射数字 1 或 5,而是将完整的数组 [1, 2, 3, 4] 或 [5, 6, 7, 8] 作为其唯一的、也是第一个值发射出去。因此,first() 操作符接收到并返回的,就是这个完整的数组。

一点PPT
一点PPT

一句话生成专业PPT,AI自动排版配图

下载

场景二:发射数组的扁平化值

与上述情况不同,RxJS 提供了一些操作符,可以将一个可迭代对象(如数组)的每个元素作为独立的事件逐个发射。from 操作符就是其中之一。

import { from } from 'rxjs';
import { first } from 'rxjs/operators';

// 示例 3: 使用 from 操作符发射数组元素
from([1, 2, 3, 4]) // from 操作符会遍历数组,将每个元素作为独立的事件逐个发射
.pipe(first())
.subscribe({
  next: (res) => console.log('示例 3 结果:', res) // 输出: 1
});

在这个示例中,from([1, 2, 3, 4]) 首先发射 1,然后发射 2,以此类推。first() 操作符在接收到第一个独立发射的值 1 后,立即将其返回并完成。这正是许多初学者期望 first 对数组进行操作时的行为。

如何处理发射数组并提取其内部元素?

如果你有一个 Observable 发射的是整个数组(如场景一),但你希望 first 操作符作用于数组内部的第一个元素,你需要先将这个数组“扁平化”,使其内部元素作为独立的事件发射出来。mergeAll 操作符可以实现这一目标。

mergeAll 的作用是将一个高阶 Observable(即发射 Observable 的 Observable)扁平化为一个低阶 Observable。当它作用于一个发射数组的 Observable 时,它会将数组视为一个“内部 Observable”(或者更准确地说,一个可迭代对象),并将其内部元素逐个发射出来。

import { of } from 'rxjs';
import { first, mergeAll } from 'rxjs/operators';

// 示例 4: 结合 of 和 mergeAll 来扁平化数组
of([1, 2, 3, 4]) // of 发射整个数组 [1,2,3,4]
.pipe(
  mergeAll(),    // mergeAll 将数组 [1,2,3,4] 扁平化,使其内部元素 1, 2, 3, 4 逐个发射
  first()        // first 接收到扁平化后的第一个元素 1
)
.subscribe({
  next: (res) => console.log('示例 4 结果:', res) // 输出: 1
});

在这个示例中,of([1, 2, 3, 4]) 首先发射 [1, 2, 3, 4] 这个数组。接着,mergeAll() 操作符会订阅这个数组(或将其视为一个可迭代的内部源),并将其中的元素 1、2、3、4 作为独立的事件依次推送到下游。此时,first() 操作符接收到的第一个事件就是 1,并将其返回。

注意事项与总结

  1. 理解 of() 与 from() 的核心区别
    • of(...args):将传入的每个参数作为一个独立的事件发射。如果参数本身是一个数组,那么这个数组会作为一个整体被发射。
    • from(iterable):遍历传入的可迭代对象(如数组、字符串、Promise 等),将每个内部元素作为独立的事件发射。
  2. first 操作符的作用对象:first 总是作用于 Observable 直接发射的第一个值。这个“值”可能是一个基本类型、一个对象,甚至是一个完整的数组。它不会自动“解包”任何复杂的数据结构。
  3. 扁平化操作符:当你需要对 Observable 发射的数组内部元素进行操作时,考虑使用 mergeAll、concatAll、switchAll 或 mergeMap、concatMap、switchMap 等扁平化操作符。它们能将高阶 Observable 或发射可迭代对象的 Observable 转换为发射单个元素的 Observable。
  4. 清晰的意图:在编写 RxJS 代码时,始终要明确你的 Observable 在每个管道阶段究竟发射的是什么类型的数据,这将帮助你正确选择和组合操作符。

通过深入理解 Observable 的发射模式以及 first 操作符的精确行为,我们可以更有效地利用 RxJS 处理复杂的数据流,避免因误解而产生的预期偏差。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

760

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

221

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1567

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

651

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

1228

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

1204

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

193

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

131

2025.08.07

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WEB前端教程【HTML5+CSS3+JS】
WEB前端教程【HTML5+CSS3+JS】

共101课时 | 10.2万人学习

JS进阶与BootStrap学习
JS进阶与BootStrap学习

共39课时 | 3.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号