简简单单的理解 RxJS 中的多播操作符(Multicasting Operators)

本文介绍了RxJS中多播操作符的概念,通过实例讲解了如何将冷Observable转换为热Observable,减少重复执行的副作用。讨论了publish、publishReplay、publishLast、publishBehavior、refCount、share和shareReplay等操作符的用法,并强调了取消订阅和处理不同订阅者需求的重要性。
摘要由CSDN通过智能技术生成

👨‍💻 介绍

对于 RxJS,多播可能是一个比较高级的概念。

这篇文章会通过一个例子,逐步的介绍多播以及多播的操作符。

🔥 Hot & cold Observables

默认情况下,大多数 Observables 都属于 Cold Observables ,每次我们订阅 Cold Observable 时,都会重新创建它的生产者。那这是什么意思?

首先,我们必须知道生产者是什么:它可以是我们 Observable 值的来源,它页可以是 DOM 事件、回调、HTTP 请求、迭代器等,总之,任何可以产生价值并将其传递给观察者的东西。

现在我们知道了生产者是什么,就更容易理解前面语句的含义了,它基本上是说我们的 Observable 的生产者在每次订阅时都会被一遍又一遍地创建。让我们看一个例子:

import { timer } from "rxjs";
import { tap } from "rxjs/operators";

const cold$ = timer(1000).pipe(tap(() => console.log("副作用")));

cold$.subscribe(val => console.log(`Observer 1: ${val}`));
cold$.subscribe(val => console.log(`Observer 2: ${val}`));

// 自这个 Cold Observable 启动,副作用就执行两次,一次是给 subscription

/* Output:
副作用,
Observer 1: 0,
副作用, 
Observer 2: 0
*/ 

如你所见,因为我们的 ObservableCold Observable ,并且它的生产者在每次订阅时都被重新创建,所以每次订阅就执行一次,副作用总共执行了两次

如果 Observable 是热的,不管我们订阅了多少次,副作用将只执行一次

举个例子来说,假设我们有一个 Ajax Observable,它可以获取一些数据。因为 Ajax ObservableCold Observable,每次订阅它时,都会发出一个新的 HTTP 请求。

20 个订阅 = 20 个 HTTP 请求。比如下面这样:

import { ajax } from "rxjs/ajax";
import { map, mergeAll, take, tap } from "rxjs/operators";

// 一个 Ajax(cold Observable)
const sharedGhibliFilm$ = ajax.getJSON("https://ghibliapi.herokuapp.com/films").pipe(tap(() => console.log("我请求啦")),mergeAll(),take(1));

// 两次 subscribe
sharedGhibliFilm$.pipe(map(({ title }) => title)).subscribe(title => console.log(`标题: ${title}`));

sharedGhibliFilm$.pipe(map(({ description }) => description)).subscribe(description => console.log(`描述: ${description}`));

// ... 两次请求

/* Output:
'我请求啦',
'标题: Castle in the Sky',
'我请求啦',
'描述: The orphan Sheeta inherited a mysterious crystal that...'
*/ 

如何才可以正确处理 热/冷 Observables 就变得很重要。

我们不想每次订阅都重新执行一遍,那就得将这个 Cold Observables 变成 Hot Observables。使用 RxJS 中的多播就可以让这件事变得很方便。

☎️ 多播 (Multicast)

多播 通过使用 Subject 共享源Observable。让我们看一个使用多播的例子:

import { interval, Subject } from "rxjs";
import { take, tap, multicast } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

const multicast$ = number$.pipe(tap(() => console.log("执行了")),multicast(() => new Subject())
);

multicast$.subscribe(console.log);
// Output: 

如果你将这段代码跑起来,你会发现它没有任何输出,这是为什么?

因为 multicast 返回一种特殊的 Observable: ConnectableObservable

这种特殊类型的 Observable 有一个connect()方法,当被调用时,它负责使用我们提供的 Subject 订阅源 Observable

这意味着如果我们不调用connect(),流永远不会被订阅,也不会

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值