前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >响应式编程在前端领域的应用

响应式编程在前端领域的应用

原创
作者头像
被删
发布于 2024-08-02 02:54:54
发布于 2024-08-02 02:54:54
6180
举报

其实在好多年前因为 Angular 的原因接触过响应式编程,而这些年的一些项目经验,让我在再次回顾响应式编程的时候又有了新的理解。

什么是响应式编程

响应式编程基于观察者模式,是一种面向数据流和变化传播的声明式编程方式。

异步数据流

响应式编程常常用在异步数据流,通过订阅某个数据流,可以对数据进行一系列流式处理,例如过滤、计算、转换、合流等,配合函数式编程可以实现很多优秀的场景。

除了天然异步的前端、客户端等 GUI 开发以外,响应式编程在大数据处理中也同样拥有高并发、分布式、依赖解耦等优势,在这种同步阻塞转异步的并发场景下会有较大的性能提升,淘宝业务架构就是使用响应式的架构。

响应式编程在前端领域

在前端领域,常见的异步编程场景包括事件处理、用户输入、HTTP 响应等。对于这类型的数据流,可以使用响应式编程的方式来进行设计。

不少开发者基于响应式编程设计了一些工具库,包括 Rxjs、Mobx、Cycle.js 等。其中,Rxjs 提供了基于可观察对象(Observable)的 functional reactive programming 服务,Mobx 提供了基于状态管理的 transparent functional reactive programming 服务,而 Cycle.js 则是一个响应式前端框架。

我们可以结合具体场景来介绍下使用,这里会以 Rxjs 来说明。

HTTP 请求与重试

基于响应式编程,我们可以很简单地实现一个请求的获取和自动重试:

代码语言:js
AI代码解释
复制
import { ajax } from "rxjs/ajax";
import { map, retry, catchError } from "rxjs/operators";

const apiData = ajax("/api/data").pipe(
  // 可以在 catchError 之前使用 retry 操作符。它会订阅到原始的来源可观察对象,此处为重新发起 HTTP 请求
  retry(3), // 失败前会重试最多 3 次
  map((res) => {
    if (!res.response) {
      throw new Error("Value expected!");
    }
    return res.response;
  }),
  catchError((err) => of([]))
);

apiData.subscribe({
  next(x) {
    console.log("data: ", x);
  },
  error(err) {
    console.log("errors already caught... will not run");
  },
});

用户输入

对应用户的一些交互,也可以通过订阅的方式来获取需要的信息:

代码语言:js
AI代码解释
复制
const observable = Rx.Observable.fromEvent(input, "input") // 监听 input 元素的 input 事件
  .map((e) => e.target.value) // 一旦发生,把事件对象 e 映射成 input 元素的值
  .filter((value) => value.length >= 1) // 接着过滤掉值长度小于 1 的
  .distinctUntilChanged() // 如果该值和过去最新的值相等,则忽略
  .subscribe(
    // subscribe 拿到数据
    (x) => console.log(x),
    (err) => console.error(err)
  );
// 订阅
observable.subscribe((x) => console.log(x));

在用户频繁交互的场景,数据的流式处理可以让我们很方便地进行节流和防抖。除此之外,模块间的调用和事件通信同样可以通过这种方式来进行处理。

比较其他技术

接触响应式编程这个概念的时候,大多数人都会对它产生困惑,也比较容易与 Promise、事件订阅这些设计混淆。我们来一起看看。

Promise

Promise 相信大家也都很熟悉,在这里拿出来比较,其实更多是将 Rxjs 中的 Observable 与之比较。这两个其实很不一样:

  • Promise 会发生状态扭转,状态扭转不可逆;而 Observable 是无状态的,数据流可以源源不断,可用于随着时间的推移获取多个值
  • Promise 在定义时就会被执行;而 Observable 只有在被订阅时才会执行
  • Promise 不支持取消;而 Observable 可通过取消订阅取消正在进行的工作

事件

同样是基于观察者模式,相信很多人都对事件和响应式编程之间的关系比较迷惑。而根据具体的设计实现,事件和响应式编程模式可以达到高度相似。

一个比较显著的区别在于,由于响应式编程是面向数据流和变化传播的模式,意味着我们可以对数据流进行配置处理,使其在把事件传给事件处理器之前先进行转换。同样由于流式处理,响应式编程可以把包含一堆异步/事件的组合从开头到结尾用流的操作符清晰表示,而原始事件回调只能表示一堆相邻节点的关系,对于数据流动方向和过程都可以进一步掌握。

同时,结合响应式编程的合流、缓存等能力,我们可以收获更多。

响应式编程提供了怎样的服务

前面说了很多,相信大家对响应式编程的概念和使用有一定的理解了。现在,我们一起来看看它还能给我们带来怎样的服务。

热观察与冷观察

在 Rxjs 中,有热观察和冷观察的概念。其中的区别:

  • Hot Observable,可以理解为现场直播,我们进场的时候只能看到即时的内容
  • Cold Observable,可以理解为点播(电影),我们打开的时候会从头播放
代码语言:js
AI代码解释
复制
let liveStreaming$ = Rx.Observable.interval(1000).take(5);

liveStreaming$.subscribe(
	data => console.log('subscriber from first second')
	err => console.log(err),
	() => console.log('completed')
)

setTimeout(() => {
	liveStreaming$.subscribe(
		data => console.log('subscriber from 2nd second')
		err => console.log(err),
		() => console.log('completed')
	)
}, 2000)
// 事实上两个订阅者接收到的值都是 0,1,2,3,4,此处为冷观察

Rxjs 中 Observable 默认为冷观察,而通过publish()connect()可以将冷的 Observable 转变成热的:

代码语言:js
AI代码解释
复制
let publisher$ = Rx.Observable.interval(1000).take(5).publish();

publisher$.subscribe(
	data => console.log('subscriber from first minute',data),
	err => console.log(err),
	() => console.log('completed')
)

setTimeout(() => {
    publisher$.subscribe(
        data => console.log('subscriber from 2nd minute', data),
        err => console.log(err),
        () => console.log('completed')
    )
}, 3000)

publisher$.connect();
// 第一个订阅者输出的是0,1,2,3,4,而第二个输出的是3,4,此处为热观察

热观察和冷观察根据具体的场景可能会有不同的需要,而 Observable 提供的缓存能力也能解决不少业务场景。例如,如果我们想要在拉群后,自动同步之前的聊天记录,通过冷观察就可以做到。同样的,热观察的用途也很广泛。

合流

流的处理大概是响应式编程中最有意思的部分了。一般来说,合流有两种方式:

代码语言:bash
AI代码解释
复制
# 1. merge
--1----2-----3--------4---
----a-----b----c---d------
           merge
--1-a--2--b--3-c---d--4---

# 2. combine
--1----2-----3--------4---
----a-----b-----c--d------
         combine
----1a-2a-2b-3b-3c-3d-4d--

那这样的合流方式,可以具体应用到哪里呢?

例如,merge 的合流方式可以用在群聊天、聊天室,一些多人协作的场景、公众号订阅的场景就可以通过这样的方式合流,最终按照顺序地展示出对应的操作记录。

再举个例子,我们在 Excel 中,通过函数计算了 A1 和 B2 两个格子的相加。这种情况下,使用 combine 方式合流符合预期,那么我们可以订阅这么一个流:

代码语言:js
AI代码解释
复制
const streamA1 = Rx.Observable.fromEvent(inputA1, "input"); // 监听 A1 单元格的 input 事件
const streamB2 = Rx.Observable.fromEvent(inputB2, "input"); // 监听 B2 单元格的 input 事件

const subscribe = combineLatest(streamA1, streamB2).subscribe((valueA1, valueB2) => {
	// 从 streamA1 和 streamB2 中获取最新发出的值
    return valueA1 + valaueB2;
});
// 获取函数计算结果
observable.subscribe((x) => console.log(x));

在一个较大型的前端应用中,通常会拆分成渲染层、数据层、网络层、其他服务等多个功能模块。虽然服务按照功能结构进行拆分了,但依然会存在服务间调用导致依赖关系复杂、事件触发和监听满天飞等情况,这种情况下,只能通过全局搜索关键字来找到上下游数据流、信息流,通过一个接一个的节点和关键字搜索才能大概理清楚某个数据来源哪里。

那么,如果使用了响应式编程,我们可以通过各种合流的方式、订阅分流的方式,来将应用中的数据流动从头到尾串在一起。这样,我们可以很清晰地当前节点上的数据来自于哪里,是用户的操作还是来自网络请求。

其他使用方式

除了上面提到的一些 HTTP 请求、用户操作、事件管理等可以使用响应式编程的方式来实现,我们还可以将定时器、数组/可迭代对象变量转换为可观察序列。

timer

也就是说,如果我们界面中有个倒计时,就可以以定时器为数据源,订阅该数据流进行响应:

代码语言:js
AI代码解释
复制
// timerOne 在 0 秒时发出第一个值,然后每 1 秒发送一次
const timerOne = timer(0, 1000).subscribe(x => {
	// 触发界面更新
});

定时器结合合流的方式,我们还可以玩出更多的花样。例如,界面中有三个倒计时,我们需要在倒计时全部结束之后展示一些内容,这个时候我们就可以通过将三个倒计时 combine 合流,当三个流都处于倒计时终止的状态时,触发相应的逻辑。

数组/可迭代对象

我们可以将数组或者可迭代的对象,转换为可观察的序列。

代码语言:js
AI代码解释
复制
var array = [1,2,3,4,5];

// 打印出每个项目
const subscription = Rx.Observable.from(array).subscribe(
	x => console.log('onNext: %s', x),
    e => console.log('onError: %s', e),
	() => console.log('onCompleted')
);

// => onNext: 1
// => onNext: 2
// => onNext: 3
// => onNext: 4
// => onNext: 5
// => onCompleted

乍一看,似乎只是将遍历换了种写法,其实这样的能力可以用在更多的地方。例如,我们在离线编辑文档的时候,做了很多操作,这些操作在本地会用一个操作记录数组的方式缓存下来。当应用检测到网络状态恢复的时候,可以将这样的操作组转换为有序的一个个操作同步到远程服务器。(当然,更好的设计应该是支持批量有序地上传操作到服务器)

结束语

对响应式编程的介绍暂告一段落。

可见对于很多复杂程度较低的前端应用来说,其实入门成本比较高。但在一些复杂应用的场景,合理地使用响应式编程,可以有效地降低各个模块间的依赖,更加容易地进行整体数据流动管理和维护。

这么有意思的东西,你要不要来试试看?

查看Github有更多内容噢: https://github.com/godbasin

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
实时视频传输中的BBR拥塞控制
在复杂的网络环境中,想要实现实时视频传输,拥塞控制算法是尤为重点的一环。本文整理自学霸君高级技术总监袁荣喜在LiveVideoStackCon 2019上海大会中的分享,详细介绍了BBR拥塞控制算法在实时视频传输中新的实践以及优缺点。
LiveVideoStack
2019/07/16
3.2K0
实时视频传输中的BBR拥塞控制
TCP拥塞控制及BBR原理分析
导语:TCP拥塞控制不仅仅是网络层的概念,可以将其归属于控制论的范畴。在TCP的演进过程中,出现了很多优秀的思想和算法,以实现网络传输过程中,在公平竞争性的前提下,尽可能地利用带宽资源。本文介绍TCP发展过程中出现的几种拥塞控制算法,并着重介绍BBR的原理。
用户4141261
2018/12/07
15.1K0
BBR及其在实时音视频领域的应用
大家好,我是网易云信音视频工程师肖磊,目前致力于实时音视频领域的QoS研究,通过优化拥塞控制算法,为用户提供高带宽利用率,低延时,抗抖动能力强的实时音视频服务。
LiveVideoStack
2019/10/15
2.4K0
一文解释清楚Google BBR拥塞控制算法原理
BBR对TCP性能的提升是巨大的,它能更有效的使用当下网络环境,Youtube应用后在吞吐量上有平均4%提升(对于日本这样的网络环境有14%以上的提升):
陶辉
2019/08/08
27.2K3
​TCP 拥塞控制详解
作者:engleliu,腾讯 PCG 开发工程师 本文主要介绍 TCP 拥塞控制算法,内容多来自网上各个大佬的博客及《TCP/IP 详解》一书,在此基础上进行梳理总结,与大家分享。因水平有限,内容多有不足之处, 敬请谅解。 一、TCP 首部格式 在了解 TCP 的拥塞控制之前,先来看看 TCP 的首部格式和一些基本概念。 TCP 头部标准长度是 20 字节。包含源端口、目的端口、序列号、确认号、数据偏移、保留位、控制位、窗口大小、校验和、紧急指针、选项等。 TCP 首部格式 1.1 数据偏移(D
腾讯技术工程官方号
2020/06/01
3.3K0
WebRTC的拥塞控制和带宽策略
在视频通信的技术领域WebRTC已成为主流的技术标准,WebRTC包涵了诸多优秀的技术,譬如:音频数字信号处理技术(AEC, NS, AGC)、编解码技术、实时传输技术、P2P技术等,这些技术目的都是为了实现更好实时音视频方案。但是在高分辨率视频通信过程中,通信时延、图像质量下降和丢包卡顿是经常发生的事,甚至在WiFi环境下,一次视频重发的网络风暴可以引起WiFi网络间歇性中断,通信延迟和图像质量之间存在的排斥关系是实时视频过程中的主要矛盾。
LiveVideoStack
2021/09/01
1.5K0
直播弱网优化方法
直播平台纷繁杂多,流量入口逐渐从传统PC端过渡至移动端。直播规 模爆发式增长,2016年更是被誉为“直播元年”。以游戏为代表的泛娱乐直播是这一时期直播生态的重要组成部分。2015-2017年,4G技术普及,手机直播由于不受设备、场景等限制开始迅速普及,推动全民直播的出现;同时,由于直播功能的创新、直播平台以及资本的纷纷入局、政策支持,直播行业一度出现“千播大战”局面。期间,政府出台《电子竞技赛事管理暂行规定》等游戏行业相关政策,进一步推动了游戏直播的发展。
视频云直播helper
2022/02/03
6.1K1
Facebook:对比COPA 与CUBIC,BBR v1在拥塞控制及视频质量的表现
原文 https://engineering.fb.com/video-engineering/copa/
LiveVideoStack
2019/11/26
1.6K0
Facebook:对比COPA 与CUBIC,BBR v1在拥塞控制及视频质量的表现
技术解码 | 直播传输技术之SRT/WebRTC
今年的双11格外疯狂,各大商家也纷纷开启了直播带货。为让广大消费者有更好的视听购物体验,腾讯视频云的小伙伴一刻也不敢放松,在做好全线护航的同时,还要保证低延迟高清流畅。随着用户对体验要求越来越高,直播进入了低延迟高码率的时代,直播传输技术也面临着越来越高的要求和挑战。 腾讯视频云为此在全链路上针对流媒体传输不断深入优化,使得在各大重要赛事上具备了高可靠、低延迟、高画质和音质的需求。下面就重点介绍其中应用的两个传输技术SRT和WebRTC。 传统TCP传输流媒体存在以下几个问题: (1) 在带宽受限
腾讯云音视频
2020/11/23
5K0
七牛云QRTC自研传输协议(QRTP)对音画质量的提升
  //   编者按:自疫情开始席卷全球,人们对音视频的需求急剧上升。在需求上升的过程中,人们对网络延迟、音画质量的要求也在不断提高。LiveVideoStackCon 2022 音视频技术大会上海站有幸邀请到了七牛云资深开发工程师——于佳老师为我们讲述QRTN的网络架构是如何提升用户体验度的,以及分析其中的QRTP协议是如何对音画质量进行提升的。 文/于佳 整理/LiveVideoStack 大家好,我是于佳,来自七牛云开发团队,我今天给大家分享的主题是七牛云QRTC自研传输协议对音画质量的提升。今天的
LiveVideoStack
2022/08/26
4990
七牛云QRTC自研传输协议(QRTP)对音画质量的提升
长肥管道传输之痛与解决之道
随着腾讯云业务的全球扩张,越来越多的海外节点在陆续的建立起来,跨海,跨洲的长距离传输也越来越成为业务的常态(像直播视频云业务就有海外主播国内乃至全球观看的业务形态)。这种远距离的数据传输,拥有长的RTT(Round Trip Time往返时间)和高的带宽,管道容量(BDP,即Bandwidth和RTT的乘积)大,被称作长肥管道。传统的TCP应用于网络不稳定的长肥管道,传输效率不高,已越来越不能满足业务稳定高速传输的苛刻要求。本文分析了长肥管道存在的问题,并提出了解决此问题的一个思路。
glendai
2019/01/15
5.2K0
长肥管道传输之痛与解决之道
C|网络|TCP-BBR拥塞控制剖析
传统TCP拥塞控制算法都是基于丢包的算法,例如收包加法增,丢包乘法减,然而基于丢包的算法无法达到理论的时延、带宽最优解。
朝闻君
2021/11/22
1.3K0
C|网络|TCP-BBR拥塞控制剖析
腾讯云音视频传输协议技术分析
导语 | 随着音视频应用的不断更新,对传输能力和体验的需求也日益增加,促进了传输技术的发展,也带了如何选择的难题。本文详解了音视频领域的几种主要传输协议,希望能够帮助大家解决实际需求和业务场景中的技术选型问题。 随着互联网的发展,Web及移动智能手机端的兴起,音视频应用也得到了蓬勃发展。同时伴随着4G/5G的商业化,人们在娱乐直播、购物、教育、医疗等领域,对于实时音视频通信的需求不断增长。直播、实时音视频等技术也开始崭露头角。 众多的音视频应用都避免不了一个问题就是,如何在现有的网络条件下,提
腾讯云音视频
2021/08/09
2.7K0
webRTC-NACK、Pacer和拥塞控制和FEC
2)NACK重新发送媒体数据有两种方式:单独RTX通道发送、与媒体数据混在一起发送
_咯噔_
2022/04/28
1.9K0
MMSys'2023 | 丢包网络多站点并行下载的 CUBIC 拥塞避免机制改进算法
视频流媒体已经快速增长,并成为主要的互联网流量。实时视频流媒体使用户能够从各种提供商(如Netflix和YouTube)检索媒体内容,并使用户能够进行实时流媒体或视频通话。随着录制和显示技术的进步,立体和360度视频可能成为未来的另一个选择。除了观看,视频流还可以应用于将物理环境与扩展现实相结合,例如角色重建和物体检测
用户1324186
2023/10/28
4850
MMSys'2023 | 丢包网络多站点并行下载的 CUBIC 拥塞避免机制改进算法
有的放矢,远程操控中实时音视频的优化之道
在上一篇文章中,我们介绍了远程操控的技术要点。从这一章开始,笔者将会依次介绍远程操控三大技术的应用及优化重点内容。本文就将会以实时音视频通信技术开始,其主要被用于解决远程操控中被操控设备或车辆周边环境画面和声音向远处控制端的实时传输,方便远程驾驶员或操控员能够清晰地了解被控设备周遭情况,从而进行针对性操控。比如车辆前进中前方和侧后方的画面,挖掘机作业过程中的抓臂画面都需要通过实时音视频技术进行远程传输。
社区小番茄
2021/12/09
1.2K0
有的放矢,远程操控中实时音视频的优化之道
新一代直播传输协议SRT
SRT协议是基于UDT的传输协议,保留了UDT的核心思想和机制,抗丢包能力强,适用于复杂的网络。在LiveVideoStack线上分享中,新浪音视频架构师 施维对SRT协议的原理、优缺点特性以及在
LiveVideoStack
2020/03/06
3.2K0
新一代直播传输协议SRT
低延时实时音视频在5G远程操控场景的应用实践
  //   编者按:随着自动驾驶技术和5G行业应用的发展,5G远程实时操控类应用逐渐兴起,用于满足高危行业/恶劣场景远程作业、自动驾驶异常情况下远程介入等需求。相比直播、会议等传统实时音视频场景,由于操控的复杂性和车辆的移动性,远程实时操控对音视频传输的时延和可靠性提出了更高的要求。 本次分享将介绍5G远程实时操控行业应用场景对音视频传输的要求,以及腾讯云音视频针对5G远程实时操控场景的音视频传输优化和应用落地实践。 文/毛峻岭 整理/LiveVideoStack 我是来自腾讯的毛峻岭,今天很高兴能够给
LiveVideoStack
2022/08/26
1.1K0
低延时实时音视频在5G远程操控场景的应用实践
【杂谈】聊聊我们关于网络拥塞与控制优化的一些技术方案
互联网上的两点通信时,每经过一个路由设备叫一跳(Hop)。而每一跳都有不同的带宽,两点之间的可用带宽是每一跳中的最小值,被称为“Bottleneck BW”。
Yangsh888
2023/02/11
1.3K0
拥塞控制
本次演讲来自Demux-SF Video Technology July 2020,主讲者是Facebook的软件工程师Nitin Garg,介绍了怎样通过更好的拥塞控制进行更有效的传输,进而提高视频质量。
用户1324186
2020/10/21
1.5K0
推荐阅读
相关推荐
实时视频传输中的BBR拥塞控制
更多 >
LV.3
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档