当前位置: 首页 > news >正文

如何使用 takeUntil RxJS 操作符来声明性地管理订阅

简介

Angular 处理取消订阅可观察对象的操作,比如从 HTTP 服务返回的可观察对象或者使用 async 管道时。然而,对于其他情况,管理所有订阅并确保取消长期存在的订阅可能会变得困难。而且,取消大部分订阅的策略也会带来自己的问题。

在本文中,您将看到一个依赖于手动订阅和取消订阅的 Angular 应用示例。然后,您将比较它与使用 takeUntil 操作符来声明性地管理订阅的 Angular 应用示例。

先决条件

如果您想跟着本文学习,您需要:

  • 对 RxJS 库有一定的了解,特别是 ObservableSubscription 将会有所帮助。
  • 对 Apollo 和 GraphQL 有一定的了解会有所帮助,但不是必需的。

本教程经过 Node v15.3.0、npm v6.14.9、@angular/core v11.0.4、rxjs v6.6.3、apollo-angular v2.1.0、graph-tag v2.11.0 的验证。本文已经根据从早期版本的 @angular/corerxjs 迁移的变化进行了编辑。

手动取消订阅

让我们从一个示例开始,您将在其中手动取消订阅两个订阅。

在这个示例中,代码正在订阅 Apollo 的 watchQuery 来从 GraphQL 端点获取数据。

该代码还创建了一个间隔可观察对象,当调用 onStartInterval 方法时,您将订阅该对象。

import { Component, OnInit, OnDestroy } from '@angular/core';import { Subscription, interval } from 'rxjs';import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';@Component({ ... })
export class AppComponent implements OnInit, OnDestroy {myQuerySubscription: Subscription;myIntervalSubscription: Subscription;constructor(private apollo: Apollo) {}ngOnInit() {this.myQuerySubscription = this.apollo.watchQuery<any>({query: gql`query getAllPosts {allPosts {titledescriptionpublishedAt}}`}).valueChanges.subscribe(({data}) => {console.log(data);});}onStartInterval() {this.myIntervalSubscription = interval(250).subscribe(value => {console.log('Current value:', value);});}ngOnDestroy() {this.myQuerySubscription.unsubscribe();if (this.myIntervalSubscription) {this.myIntervalSubscription.unsubscribe();}}
}

现在想象一下,您的组件有许多类似的订阅,当组件被销毁时,确保一切都被取消订阅可能会变得相当复杂。

使用 takeUntil 声明性地取消订阅

解决方案是使用 takeUntil 操作符来组合订阅,并使用一个在 ngOnDestroy 生命周期钩子中发出真值的主题。

以下代码片段执行了完全相同的操作,但这次代码将以声明性的方式取消订阅。您会注意到一个额外的好处是,您不再需要保留对我们订阅的引用。

import { Component, OnInit, OnDestroy } from '@angular/core';import { Subject, interval } from 'rxjs';
import { takeUntil } from 'rxjs/operators';import { Apollo } from 'apollo-angular';
import gql from 'graphql-tag';@Component({ ... })
export class AppComponent implements OnInit, OnDestroy {destroy$: Subject<boolean> = new Subject<boolean>();constructor(private apollo: Apollo) {}ngOnInit() {this.apollo.watchQuery<any>({query: gql`query getAllPosts {allPosts {titledescriptionpublishedAt}}`}).valueChanges.pipe(takeUntil(this.destroy$)).subscribe(({data}) => {console.log(data);});}onStartInterval() {interval(250).pipe(takeUntil(this.destroy$)).subscribe(value => {console.log('Current value:', value);});}ngOnDestroy() {this.destroy$.next(true);this.destroy$.unsubscribe();}
}

请注意,使用 takeUntil 这样的操作符而不是手动取消订阅也将完成可观察对象,触发可观察对象上的任何完成事件。

请确保检查您的代码,以确保这不会产生任何意外的副作用。

结论

在本文中,您学习了如何使用 takeUntil 声明性地取消订阅。取消不必要的订阅有助于防止内存泄漏。声明性地取消订阅使您不需要对订阅保留引用。

还有其他类似的 RxJS 操作符 - 如 taketakeWhilefirst - 它们都会完成可观察对象。

如果您想了解更多关于 Angular 的知识,请查看我们的 Angular 主题页面,了解练习和编程项目。

相关文章:

如何使用 takeUntil RxJS 操作符来声明性地管理订阅

简介 Angular 处理取消订阅可观察对象的操作&#xff0c;比如从 HTTP 服务返回的可观察对象或者使用 async 管道时。然而&#xff0c;对于其他情况&#xff0c;管理所有订阅并确保取消长期存在的订阅可能会变得困难。而且&#xff0c;取消大部分订阅的策略也会带来自己的问题。…...

在Centos中用Docker部署oracle-12c

一、介绍 Oracle 12c是Oracle 11g的后续版本。12c代表云计算&#xff08;Cloud Computing&#xff09;&#xff0c;这是Oracle在该版本中强调的一个关键概念。它具有多租户架构、数据库内存、安全增强、大数据管理和自动化管理等功能。它被广泛应用于企业级应用程序和大型数据…...

JS进阶——高级技巧

版权声明 本文章来源于B站上的某马课程&#xff0c;由本人整理&#xff0c;仅供学习交流使用。如涉及侵权问题&#xff0c;请立即与本人联系&#xff0c;本人将积极配合删除相关内容。感谢理解和支持&#xff0c;本人致力于维护原创作品的权益&#xff0c;共同营造一个尊重知识…...

TG-ADMIN 权限管理系统

项目简介 该项目是一款基于 SpringBoot + Vue2 + Jwt + ElementUi的 RBAC模型管理系统。 主要以自定义拦截器和jwt结合进行权限验证 通过自定义指令实现按钮级别权限,使用经典的RBAC模型 什么是RBAC? 1、RBAC模型概述 RBAC模型(Role-Based Access Control:基于角色的…...

十五届蓝桥杯第三期模拟赛题单(C++、java、Python)

备战2024年蓝桥杯 省赛第三期模拟赛题单 备战Python大学A组 第一题 【问题描述】 请问 2023 有多少个约数&#xff1f;即有多少个正整数&#xff0c;使得 2023 是这个正整数的整数倍。 【问题描述】 这是一道结果填空的题&#xff0c;你只需要算出结果后提交即可。本题的结果…...

嵌入式驱动学习第一周——git的使用

前言 本文主要介绍git的使用&#xff0c;包括介绍git&#xff0c;gitee&#xff0c;以及使用gitee创建仓库并托管代码 嵌入式驱动学习专栏将详细记录博主学习驱动的详细过程&#xff0c;未来预计四个月将高强度更新本专栏&#xff0c;喜欢的可以关注本博主并订阅本专栏&#xf…...

界面控件DevExpress .NET MAUI v23.2新版亮点 - 拥有全新的彩色主题

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布&#xff0c;该版本拥有众多…...

大语言模型LLM Pro+中Pro+(Prompting)的意义

—— Pro &#xff0c;即Prompting&#xff0c;构造提示 1.LLM Pro中Pro&#xff08;Prompting&#xff09;的意义 Prompting不仅是大语言模型交互和调用的一种高效手段&#xff0c;而且已成为推动模型泛化能力和应用灵活性的关键技术路径&#xff0c;它不仅极大地拓展了模型功…...

React 中,children 属性

在 React 中&#xff0c;children 属性是一个特殊的属性&#xff0c;它允许你将组件作为其他组件的子元素传递。这意味着你可以在组件内部嵌套任何类型的子组件或元素&#xff0c;并且在父组件中通过 props.children 访问它们。这为组件的复用和组合提供了极大的灵活性。 以下…...

多行业万能预约门店小程序源码系统 支持多门店预约小程序 带完整的安装代码包以及搭建教程

随着消费者对于服务体验要求的不断提升&#xff0c;门店预约系统成为了许多行业提升服务质量、提高运营效率的重要工具。然而&#xff0c;市面上的预约系统往往功能单一&#xff0c;无法满足多行业、多场景的个性化需求。下面&#xff0c;小编集合了多年的行业经验和技术积累&a…...

Node.js 中 fs 模块文件操作的应用教程

Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境&#xff0c;它可以让 JavaScript 代码在服务器端运行。在 Node.js 中&#xff0c;fs 模块是用来处理文件系统操作的模块。通过 fs 模块&#xff0c;我们可以进行文件的读取、写入、删除等操作。本教程将介绍如何在 No…...

一些常用到的git命令

git stash -a //缓存所有文件 git checkout -b dev origin/dev //切换到dev分支上,接着跟远程的origin地址上的dev分支关联起来 //推送本地分支到远程仓库 git push origin localbranchname:remotebrancname git revert onefile //https://www.freecodecamp.org/news/git-re…...

spring boot3解决跨域的几种方式

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 1.前言 2.何为跨域 3.跨域问题出现特征 4.方式一&#xff1a;使用 CrossOrigin 注解 5.方式二&#xff1a;自定义…...

【Spring】19 @Autowired注解使用详解

文章目录 构造函数注入Setter方法注入字段注入数组和集合注入特殊情况处理特殊接口类型的注入异常处理结语 Spring 框架的 Autowired 注解是实现依赖注入的一种强大而灵活的方式。在本文中&#xff0c;我们将介绍 Autowired 注解的多种用法&#xff0c;包括构造函数、setter方法…...

Educational Codeforces Round 132 (Rated for Div. 2) E. XOR Tree(启发式合并+贪心)

题目 n(n<2e5)个点的树&#xff0c;点i权值ai&#xff08;1<ai<2^30&#xff09; 修改最少的点的权值&#xff0c;使得树上不存在异或和为0的简单路径&#xff0c;输出最少的点数 权值可以被修改成任意正整数&#xff08;可以是无限大&#xff09; 思路来源 官方…...

JavaScript 基本数据类型的详解

JavaScript的基本数据类型 以下都是JS内置的几种类型 数据类型描述number数字&#xff0c;不区分整数和小数string字符串类型booleantrue 真, false 假undefined表示未定义的值null只有唯一的值 null&#xff0c;表示空值 number 数字类型 JavaScript 中不区分整数和浮点数&…...

DDR5内存相比DDR4内存的优势和区别?选择哪一个服务器内存配置能避免丢包和延迟高?

根据幻兽帕鲁服务器的实际案例分析&#xff0c;选择合适的DDR4与DDR5内存大小以避免丢包和延迟高&#xff0c;需要考虑以下几个方面&#xff1a; 性能与延迟&#xff1a;DDR5内存相比DDR4在传输速率、带宽、工作电压等方面都有显著提升&#xff0c;但同时也伴随着更高的延迟。D…...

篮球游戏中的挑战精神与怄气心理:扣篮被帽后的再度冲击

在篮球比赛中&#xff0c;扣篮无疑是最具观赏性和震撼力的动作之一&#xff0c;它展示了球员的爆发力、技巧和自信。而在篮球游戏中&#xff0c;玩家即便面临连续扣篮被盖帽的挫折&#xff0c;仍渴望继续杀入内线尝试扣篮的现象&#xff0c;实则是体育竞技精神、挑战意识与怄气…...

JavaScript高级程序设计

前言 《JavaScript高级程序设计》 第1章——什么是JavaScript DOM将整个页面抽象为一组分层节点。 BOM用于支持访问和操作浏览器的窗口。 第2章——HTML中的JavaScript 2.1 < script >元素 元素描述async立即开始下载脚本&#xff0c;但不能阻止其他页面动作&#…...

初阶数据结构:栈与队列

目录 1. 简述&#xff1a;栈2. 栈的功能分析与实现2.1 功能分析2.2 栈的实现2.2.1 栈的结构创建与初始化2.2.2 压栈&#xff0c;出栈与判空&#xff1a;2.2.3 获取栈顶元素&#xff0c;检索栈的长度与栈的销毁 3. 简述&#xff1a;队列4. 队列的功能分析与实现4.1 队列的功能分…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

React hook之useRef

React useRef 详解 useRef 是 React 提供的一个 Hook&#xff0c;用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途&#xff0c;下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

跨链模式:多链互操作架构与性能扩展方案

跨链模式&#xff1a;多链互操作架构与性能扩展方案 ——构建下一代区块链互联网的技术基石 一、跨链架构的核心范式演进 1. 分层协议栈&#xff1a;模块化解耦设计 现代跨链系统采用分层协议栈实现灵活扩展&#xff08;H2Cross架构&#xff09;&#xff1a; 适配层&#xf…...

Python如何给视频添加音频和字幕

在Python中&#xff0c;给视频添加音频和字幕可以使用电影文件处理库MoviePy和字幕处理库Subtitles。下面将详细介绍如何使用这些库来实现视频的音频和字幕添加&#xff0c;包括必要的代码示例和详细解释。 环境准备 在开始之前&#xff0c;需要安装以下Python库&#xff1a;…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...