布莱恩F爱
向来自波特兰的谷歌开发者专yobet英雄联盟家学习Angular、Web技术和Node.js。
广告 ·ultimatecourses.com
使用Ultimate Courses以正确的方式学习Angular

RxJS:基础知识

通过RxJS学习Angular中函数式响应式编程的基础知识。

为什么?

你可能会问:

Angular和函数式响应式编程有什么关系?

实际上,很多。
Angular中所有异步的东西都是可观测的,这是响应式编程的核心。

如果你习惯使用承诺,可观察对象是非常简单的。一个简单的解释是,可观察对象就像可以在一段时间内发出多个值的承诺——或者称为流。当然,这有点简化了,但对我们来说这是一个起点。

Meetup演讲

本文主要基于我在2018年2月落基山Angular会议上的一次会议演示。看看YouTube上的视频:

演示文件

在这篇文章中,我将引用一些我为演示而放在一起的演示文件。你可以通过以下途径下载:

演示文件使用webpack-dev-server。所有的演示都包含在里面<年代trong>src /演示目录,您可以切换哪个演示正在运行<年代trong>src / index.tswebpack的入口点。只需取消您想要执行的演示程序的注释,然后加载http://localhost:8080在您的浏览器中。演示文件或索引文件的任何更改和浏览器将实时重新加载更新后的更改。当然,确保每次只运行一个演示程序(为了清晰起见)。

RxJS是什么?

RxJS是ReactiveX库的JavaScript实现。ReativeX使我们作为Angular开发人员能够构建异步、模块化、基于事件的应用程序。它允许我们开发这些应用反应性地.一开始,这有点让人困惑,但随着你深入RxJS,你会开始了解这个概念是多么强大,以及RxJS提供的许许多多运算符是多么强大。

回到数据流的概念。在承诺使一个异步事件或值被满足或拒绝时,RxJS启用多个要观察的异步事件或值。

这是新的吗?

是的,没有。是的,这对我们作为JavaScript开发人员来说可能是新的。但是,这个概念或设计模式并不是新的。

如果你指的是著名的四组设计模式书你会发现观察者设计模式

观察者设计模式由观察者实现

简单解释一下这个概念:

  • 一个主题类包含一组观察者。
  • 每一个ConcreteObserver扩展一个抽象观察者类,实现update ()方法。
  • 对象注册自己主题,也可以注销自己的注册。
  • 主题通知所有观察者事件或值。

可见是什么?

简单地说,可观察对象实现了观察者设计模式。一个观察者(或多个观察者)接收一个通知这是由可观察对象发射的。

在RxJS中,这是由恰当的名称表示的可观测的类,它包含静态方法和实例方法,用于创建类的实例、过滤和转换由可观察对象发出的值等等。此外,可观测的方法围绕Array.prototypeJavaScript开发人员熟悉的方法,包括:filter ()map ()reduce ()等。

从Promiseland

为了了解我们从哪里来,到哪里去,让我们快速回顾一下承诺.简单地取消进口“。/演示/承诺”;线<年代trong>src / index.ts文件。这里是内容<年代trong>src /演示/ promise.ts文件:

/*创建一个新的承诺。*/常量p<年代p一个class="token operator">=承诺解决=>setTimeout=>解决“从Promiseland你好!”1000/*记录发出的单个值。*/p<年代p一个class="token punctuation">.然后价值=>控制台<年代p一个class="token punctuation">.日志价值<年代p一个class="token punctuation">)

快速回顾:

  • 承诺类已经融入了我们的浏览器。因此,我们不需要从库中导入任何东西。
  • 我们创建一个新的承诺,提供executor函数,该函数接受两个参数,a解决函数和一个拒绝函数。在这个演示中,我们只使用解决函数。
  • 异步事件将导致承诺要么被实现,要么被拒绝。
  • 在本例中,我们只是使用setTimeout ()函数以类似于异步事件。一秒钟后,将发出字符串值“Hello from Promiseland”。

对Observableland

假设我们对单个异步值有承诺,那么可观察对象提供了随时间发出值流的能力。让我们看一个简单的例子<年代trong>src /演示/ observable.ts:

进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”/*创建一个新的可观察对象,提供subscribe函数。*/常量可观测的<年代p一个class="token operator">:可观测的<年代p一个class="token operator"><字符串<年代p一个class="token operator">>可观测的观察者=>常量时间间隔<年代p一个class="token operator">=setInterval=>观察者<年代p一个class="token punctuation">.下一个“从Observableland你好!”1000/ /拆卸返回=>clearInterval时间间隔<年代p一个class="token punctuation">)/*订阅通知。*/可观测的<年代p一个class="token punctuation">.订阅价值=>控制台<年代p一个class="token punctuation">.日志价值<年代p一个class="token punctuation">)
  • 首先,我们需要导入可观测的因为可观察对象还不是ECMAScript (JavaScript)语言的一部分。
  • 然后,我们创建一个新的可观测的,提供订阅函数,该函数在观察者订阅可观察对象。
  • 我们可以使用next ()方法在一个观察者对象向观察器发送值。的观察者Interface要求对象实现三个方法:next ()抓住()完成()
  • 在这个例子中,我们使用setInterval ()函数来模拟将随时间发出值的异步事件。每一秒我们都会发出字符串“Hello from Observableland!”
  • 然后我们返回一个拆卸函数,当所有观察者都从可观察对象中取消订阅时调用该函数。
  • 最后,我们调用订阅()方法提供一个函数,该函数在每次next ()值被发送给所有观察者。

什么是通知

通知类表示或包装由可观察流发出的事件或值。通知被通过一个可观测的观察员,并包括元数据类型的事件或价值:如果事件或流值是下一个值,或者如果该值是一个例外,如果流已经完成并将不再发出任何未来值。

什么是观察者

一个观察者收到一个通知从一个可观测的并由订阅.一个观察者将反应下一个错误完成通知。

在Angular中,我们通常是框架中可观察对象发出的异步事件或值的消费者或观察者。Angular中一些常见的用例是HTTP请求和路由参数。

什么是订阅

一个订阅是可观察对象和观察者之间的联系。调用时将返回订阅对象订阅()方法在一个可观测的.订阅对象有两个重要的方法:退订()add ().的退订()方法将从可观察对象的观察者集合中删除一个观察者,以及任何子订阅对象。控件可以将子订阅添加到现有订阅add ()方法。

这包含在ECMAScript中吗?

还没有。

可观察对象目前是一个第一阶段的建议由Ecma国际内部的TC39小组为ECMAScript,它是JavaScript实现的。我们应该期待在“不久”的将来看到可观察到的内容被写入浏览器。

在那之前,我们需要使用像RxJS这样的库。而且,在撰写本文时,这个可观察的建议并没有包括许多RxJS中包含的响应式编程操作符。因此,在可预见的未来,我们可能会使用RxJS。

什么是主题

一个主题是一个专门的可观察对象,它使我们能够向许多观察者多播值,并且有几个已实现的行为。因为主题类继承了可观测的它继承了可观察对象的所有相同的方法和属性。所以,一个主体既是一个可观察对象又是一个观察者。这是我们需要学习的一个重要而有力的概念。

让我们来看看<年代trong>src /演示/ subject.ts:

进口主题<年代p一个class="token punctuation">}“rxjs /主题”/*创建一个Subject实例。*/常量年代<年代p一个class="token operator">=主题<数量<年代p一个class="token operator">>/*订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志1:之前的下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志“之前完成1”年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志2:之前的下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志2之前完成的/*发出一些值。*/年代<年代p一个class="token punctuation">.下一个1年代<年代p一个class="token punctuation">.下一个2年代<年代p一个class="token punctuation">.下一个3./*迟订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志”后,“下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志完成后的/*延迟订阅现在将收到通知。*/年代<年代p一个class="token punctuation">.下一个4年代<年代p一个class="token punctuation">.完整的

在这个例子中:

  • 我们进口主题类,然后创建一个新实例。
  • 我使用的是TypeScript,所以我指定了这个主题的泛型类型为type数量.这意味着我可以期望可观察流发出的值是数字。
  • 接下来,我们创建两个新订阅。我们为这三个通知提供了一个回调函数:下一个完成,按此顺序作为订阅()方法。
  • 我只是将通知的结果注销到控制台。
  • 然后,使用next ()方法:1、2、3。
  • 然后在发出前三个值之后添加第三个订阅。
  • 然后,使用next ()方法:4。
  • 最后,我们完成()可观察流,通知观察者流将不再发出未来的值。

如果您检查控制台,您应该看到:

以前1:1以前2:1以前1:2以前2:2以前1:3以前2:3以前1:4以前2:4以后:4完成以前1完成以前2完成以后

注意,订阅可观察对象的顺序很重要,因为第三个订阅只接收第四个值(4)主题我们可以调用observable吗next ()方法向观察者发出附加值。

什么是AsyncSubject

AsyncSubject类继承了主题继承a的所有方法和属性主题.还有,别忘了主题扩展Obserable

AsyncSubject是三个不同的吗主题由RxJS库实现的行为。我们会看一下所有这些。

这里有一个例子,位于<年代trong>src /演示/ async-subject.ts:

进口AsyncSubject<年代p一个class="token punctuation">}“rxjs / AsyncSubject”/*创建AsyncSubject的实例。*/常量年代<年代p一个class="token operator">=AsyncSubject<数量<年代p一个class="token operator">>/*订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志“:”下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志之前完成的/*发出一些值。*/年代<年代p一个class="token punctuation">.下一个1年代<年代p一个class="token punctuation">.下一个2年代<年代p一个class="token punctuation">.下一个3./*迟订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志”后,“下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志完成后的/*完成可观察流。*///我们必须完成这样的值被发送到订阅年代<年代p一个class="token punctuation">.完整的

这个例子如果非常类似于前面的例子主题类。最主要的区别是AsyncSubject将仅接收最后发出的值,且仅在完成时。

在控制台中,你应该看到:

Before: 3 after: 3 complete Before: 3 complete after

注意,订阅可观察流的顺序是不相关的。您也可以通过注释掉完成()方法调用。当您这样做时,您应该不会在控制台中看到任何内容,因为观察者永远不会收到通知。

什么是BehaviorSubject

当观察者订阅BehaviorSubject它接收由可观察对象发出的最新通知,然后继续接收未来的通知,直到流完成。为了实现这一点,我们必须在创建新文件时提供种子(或默认)值BehaviorSubject

让我们看一个例子<年代trong>src /演示/ behavior-subject.ts文件:

进口BehaviorSubject<年代p一个class="token punctuation">}“rxjs / BehaviorSubject”/*创建一个实例的行为主体。*/常量年代<年代p一个class="token operator">=BehaviorSubject<数量<年代p一个class="token operator">>0/*订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志“:”下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志之前完成的/*发出一些值。*/年代<年代p一个class="token punctuation">.下一个1年代<年代p一个class="token punctuation">.下一个2年代<年代p一个class="token punctuation">.下一个3./ / s.complete ();/*迟订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志”后,“下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志完成后的

快速回顾:

  • 首先,我们导入BehaviorSubject类,然后创建一个提供种子值的新实例。
  • 接下来,我们订阅可观察流。
  • 然后,我们发出三个值:1、2、3。
  • 然后再次进行订阅(在发出三个值之后)。

下面是登录到控制台的内容:

Before: 0 Before: 1 Before: 2 Before: 3 after: 3

有几点需要注意:

  • 请注意,在我们调用之前创建的订阅next ()收到种子值为0。
  • 注意,在我们发出第三个值(3)之后创建的订阅也收到了最新的通知。
  • 如果您取消注释调用完成(),请注意,第二个订阅永远不会接收下一个通知,但仍然收到完成通知。

什么是ReplaySubject

顾名思义,aReplaySubject向任何观察者发出源可观察对象发出的所有通知,而不管观察者什么时候订阅。

让我们看一个例子<年代trong>src /演示/ replay-subject.ts:

进口ReplaySubject<年代p一个class="token punctuation">}“rxjs / ReplaySubject”/*创建一个ReplaySubject实例。*/常量年代<年代p一个class="token operator">=ReplaySubject<数量<年代p一个class="token operator">>/*订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志“:”下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志之前完成的/*发出一些值。*/年代<年代p一个class="token punctuation">.下一个1年代<年代p一个class="token punctuation">.下一个2年代<年代p一个class="token punctuation">.下一个3./*迟订阅主题。*/年代<年代p一个class="token punctuation">.订阅下一个=>控制台<年代p一个class="token punctuation">.日志”后,“下一个<年代p一个class="token punctuation">)错误=>控制台<年代p一个class="token punctuation">.警告错误<年代p一个class="token punctuation">)=>控制台<年代p一个class="token punctuation">.日志完成后的/*完成可观察流。*/年代<年代p一个class="token punctuation">.完整的

上面的代码与前面的示例非常相似。注意,我们发出完成两次订阅后的通知。

下面是输出到控制台的内容:

Before: 1 Before: 2 Before: 3 after: 1 after: 2 after: 3 complete Before: complete after

在本例中,无论何时创建订阅,两个订阅都将接收所有通知。

单播和多播

一个可观测的是单播的,因为每个订阅的观察者都拥有一个独立的可观察对象的执行。

让我们看一个示例,它将向我们展示,对于每个订阅,我们将执行订阅函数这是提供给可观测的构造函数()函数。

演示程序位于<年代trong>src /演示/ obserable-unicast.ts文件:

进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”/*创建一个新的可观察对象,提供subscribe函数。*/我<年代p一个class="token operator">=0常量可观测的<年代p一个class="token operator">:可观测的<年代p一个class="token operator"><数量<年代p一个class="token operator">>可观测的观察者=>控制台<年代p一个class="token punctuation">.日志' % cNew创建订阅的背景:# 222;颜色:# bada55”我<年代p一个class="token operator">++常量时间间隔<年代p一个class="token operator">=setInterval=>观察者<年代p一个class="token punctuation">.下一个我<年代p一个class="token punctuation">)1000返回=>clearInterval时间间隔<年代p一个class="token punctuation">)/*每个订阅都会收到一个Observer副本。*/常量订阅<年代p一个class="token operator">=可观测的<年代p一个class="token punctuation">.订阅价值=>控制台<年代p一个class="token punctuation">.日志“第一订阅”价值<年代p一个class="token punctuation">)订阅<年代p一个class="token punctuation">.添加可观测的<年代p一个class="token punctuation">.订阅价值=>控制台<年代p一个class="token punctuation">.日志“第二个订阅”价值<年代p一个class="token punctuation">)/* 5秒后取消订阅。*/setTimeout=>订阅<年代p一个class="token punctuation">.退订5000

在这个例子中,我们应该看到subscribe函数被调用了两次,对于每个可观察流的观察者:

缺省情况下,可观察对象为单播

我们观察到(ha)创建了两个新订阅,结果值为是2。

注意这一点很重要,因为将为每个订阅调用订阅函数中的代码。如果我们正在执行一个任务,比如一个HTTP请求或一个长时间运行的代码块,那么每次创建新的订阅时都会执行这个任务。如果我们想避免这个,我们可以用a主题使用对源可观察流的单个订阅向所有观察者多播相同的通知。

让我们来看看多播<年代trong>src /演示/ subject-multicast.ts:

进口观察者<年代p一个class="token punctuation">}“rxjs /观察者”进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”进口发布<年代p一个class="token punctuation">,takeWhile<年代p一个class="token punctuation">}“rxjs /运营商”进口ConnectableObservable<年代p一个class="token punctuation">}“rxjs /可见/ ConnectableObservable”进口“rxjs /添加/可观测间隔”/ *组件状态。*/活着<年代p一个class="token operator">=真正的/*创建一个新的可观察对象,提供subscribe函数。*/我<年代p一个class="token operator">=0常量可观测的<年代p一个class="token operator">=可观测的<数量<年代p一个class="token operator">>观察者=>控制台<年代p一个class="token punctuation">.日志' % cNew创建订阅的背景:# 222;颜色:# bada55”我<年代p一个class="token operator">++常量时间间隔<年代p一个class="token operator">=setInterval=>观察者<年代p一个class="token punctuation">.下一个我<年代p一个class="token punctuation">)1000返回=>clearInterval时间间隔<年代p一个class="token punctuation">)takeWhile=>活着<年代p一个class="token punctuation">)常量多播<年代p一个class="token operator">:ConnectableObservable<年代p一个class="token operator"><数量<年代p一个class="token operator">>可观测的<年代p一个class="token punctuation">.发布/*创建两个订阅多播<年代p一个class="token punctuation">.订阅价值=>控制台<年代p一个class="token punctuation">.日志“第一订阅”价值<年代p一个class="token punctuation">)多播<年代p一个class="token punctuation">.订阅价值=>控制台<年代p一个class="token punctuation">.日志“第二个订阅”价值<年代p一个class="token punctuation">)/*连接subject和observabe。*/多播<年代p一个class="token punctuation">.连接/* 5秒后完成可观察对象。*/setTimeout=>活着<年代p一个class="token operator">=5000

这一次,我们注意到subscribe函数只执行了一次,并且所有的观察者都收到了来自源可观察对象的通知:

多播的主题

  • 首先,我们看到订阅函数只被调用一次,因此是1。
  • 然后,每个观察者收到下一个相同值的通知:1。
  • 最后,可观察对象在5秒后完成。

热与冷

我们要讨论的最后一个概念是确定一个可观察物体是“热”还是“冷”。如果一个可观察对象的生产者(或事件或值的来源)只会在一个可观察对象的订阅中产生一个事件或值,那么这个可观察对象就被认为是冷的。另一方面,如果一个可观察对象的生产者不在可观察对象的范围内,那么该可观察对象就被认为是热的订阅函数。换句话说,这个可观察对象关闭了一个已经产生的生产者。

让我们来看一个例子,在<年代trong>src /演示/ observable-cold.ts文件:

进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”进口观察者<年代p一个class="token punctuation">}“rxjs /观察者”进口作为io<年代p一个class="token keyword">从“socket.io-client”//确保启动socket。io年代erver via `yarn start:server`/*创建一个新的可观察对象,提供subscribe函数。*/常量消息<年代p一个class="token operator">=可观测的<年代p一个class="token punctuation">.创建观察者<年代p一个class="token operator">:观察者<年代p一个class="token operator"><任何<年代p一个class="token operator">>=>控制台<年代p一个class="token punctuation">.日志' % cNew创建订阅的背景:# 222;颜色:# bada55”常量url<年代p一个class="token operator">=“localhost: 3000”常量套接字<年代p一个class="token operator">:SocketIOClient<年代p一个class="token punctuation">.套接字<年代p一个class="token operator">=iourl<年代p一个class="token punctuation">)套接字<年代p一个class="token punctuation">.“消息”数据<年代p一个class="token operator">:任何=>观察者<年代p一个class="token punctuation">.下一个数据<年代p一个class="token punctuation">)返回=>套接字<年代p一个class="token punctuation">.断开连接/*可观察对象在被订阅之前是冷的。*/消息<年代p一个class="token punctuation">.订阅消息<年代p一个class="token operator">:任何=>控制台<年代p一个class="token punctuation">.日志消息<年代p一个class="token punctuation">)

在执行上面的示例之前,请确保启动了套接字。io服务器通过:

$<年代p一个class="token function">纱启动:服务器

在上面的例子中,我们是:

  • 使用静态创建一个可观察对象create ()方法,提供订阅函数。
  • 创建一个套接字。io年代erver within the订阅函数,以便服务器仅在可观察对象的新观察者上创建。
  • 喷出的下一个当从套接字服务器接收到新消息时通知。
  • 使用teardown功能断开与socket服务器的连接。

因为这是一个冷观察者,所以生产者(在本例中是到套接字服务器的连接)只在调用时创建订阅()方法。如果注释掉创建新订阅的行,那么生成器将不会生成值(在本例中是来自套接字服务器的消息)。

反过来,让我们来看看什么是热可观测物体<年代trong>src /演示/可见-热- 1. - ts:

进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”进口观察者<年代p一个class="token punctuation">}“rxjs /观察者”进口作为io<年代p一个class="token keyword">从“socket.io-client”//确保启动socket。io年代erver via `yarn start:server`/*在观察者外部创建单个连接,以避免多个连接。*/套接字<年代p一个class="token operator">:SocketIOClient<年代p一个class="token punctuation">.套接字<年代p一个class="token punctuation">;常量url<年代p一个class="token operator">=“localhost: 3000”套接字<年代p一个class="token operator">=iourl<年代p一个class="token punctuation">)/*创建一个新的可观察对象,提供subscribe函数。*/常量消息<年代p一个class="token operator">=可观测的<年代p一个class="token punctuation">.创建观察者<年代p一个class="token operator">:观察者<年代p一个class="token operator"><任何<年代p一个class="token operator">>=>控制台<年代p一个class="token punctuation">.日志' % cNew创建订阅的背景:# 222;颜色:# bada55”套接字<年代p一个class="token punctuation">.“消息”数据<年代p一个class="token operator">:任何=>观察者<年代p一个class="token punctuation">.下一个数据<年代p一个class="token punctuation">)/*多个订阅将打开单个连接。*/// const订阅=消息。订阅((消息:任何)=>控制台.日志(“第一订阅”,消息));/ / subscription.add(消息。订阅((消息:任何)=>控制台.日志(“第二个订阅”,消息)));// setTimeout(() => subscribe .unsubscribe(), 6000);

在上述代码中:

  • 我们在可观察对象的外部创建一个到套接字服务器的连接订阅函数。
  • 我们发出下一个每次套接字发出消息时通知。
  • 现在我们没有创建任何订阅。但是,我们的套接字服务器连接仍然建立。
  • 如果取消注释最后几行代码,我们将观察到,即使我们正在创建两个订阅,也只建立了一个到套接字服务器的连接。

这是因为可观察对象已经是“热的”并且产生了值。

这如何应用到Angular?一个例子是HttpClientModule.如果我们调用get ()方法HttpClient,我们将观察到GET网络请求仅在订阅()对象返回的可观察对象get ()方法。此外,我们还将观察到,对于每一个创建的新订阅,都会发出一个附加请求。这是因为多次订阅可观察对象将创建多个生产者的实例。

最后,我们可以使用分享()操作符。我们来看看这个<年代trong>src /演示/ obserable -热- 2. - ts文件:

进口可观测的<年代p一个class="token punctuation">}“rxjs /可见”进口观察者<年代p一个class="token punctuation">}“rxjs /观察者”进口分享<年代p一个class="token punctuation">}“rxjs /运营商”进口作为io<年代p一个class="token keyword">从“socket.io-client”//确保启动socket。io年代erver via `yarn start:server`/*创建一个新的可观察对象,提供subscribe函数。*/套接字<年代p一个class="token operator">:SocketIOClient<年代p一个class="token punctuation">.套接字<年代p一个class="token punctuation">;常量url<年代p一个class="token operator">=“localhost: 3000”常量消息<年代p一个class="token operator">=可观测的<年代p一个class="token punctuation">.创建观察者<年代p一个class="token operator">:观察者<年代p一个class="token operator"><任何<年代p一个class="token operator">>=>控制台<年代p一个class="token punctuation">.日志' % cNew创建订阅的背景:# 222;颜色:# bada55”套接字<年代p一个class="token operator">=iourl<年代p一个class="token punctuation">)套接字<年代p一个class="token punctuation">.“消息”数据<年代p一个class="token operator">:任何=>观察者<年代p一个class="token punctuation">.下一个数据<年代p一个class="token punctuation">)返回=>套接字<年代p一个class="token punctuation">.断开连接分享/*多个订阅将打开单个连接。*/常量订阅<年代p一个class="token operator">=消息<年代p一个class="token punctuation">.订阅消息<年代p一个class="token operator">:任何=>控制台<年代p一个class="token punctuation">.日志“第一订阅”消息<年代p一个class="token punctuation">)订阅<年代p一个class="token punctuation">.添加消息<年代p一个class="token punctuation">.订阅消息<年代p一个class="token operator">:任何=>控制台<年代p一个class="token punctuation">.日志“第二个订阅”消息<年代p一个class="token punctuation">)setTimeout=>订阅<年代p一个class="token punctuation">.退订6000

在上面的例子中,我们使用管()方法,提供分享()操作符。的分享()操作符返回一个多排且热的新可观察对象。

想了解更多细节,请查看本的帖子热的和冷的观测

布莱恩F爱

嗨,我是布莱恩。我对TypeScript、Angular和Node.js感兴趣。我和我最好的朋友邦妮结婚了,我住在波特兰,我经常滑雪。