rxjs用简单的英语解释

React式编程(Reactive Programming)

介绍(Introduction)

Do you want to start learning RxJs but get confused with some of the terminology that surrounds it? Or are you already using it and want to understand it in an easier way?

您是否想开始学习RxJ,但对周围的一些术语感到困惑? 还是您已经在使用它并希望以更简单的方式理解它?

Either way you’re in the right place. In this post you’ll learn

无论哪种方式,您都处在正确的位置。 在这篇文章中,您将学习

  • the terminology used in RxJs

    RxJ中使用的术语
  • the roles that an Observer, Observable, Subscriber and Operator play and their responsibilities

    观察者,可观察者,订阅者和操作者所扮演的角色及其职责
  • how to create an Observable using various methods.

    如何使用各种方法创建一个Observable。
  • and seven of the most often used operators and how they work

    以及七个最常用的运算符及其工作方式

There’s a lot to cover in the land of RxJs but this post should get you up and running with what’s going on in the library.

RxJs领域涉及很多内容,但是这篇文章应该使您掌握并运行库中发生的一切。

Note: All examples used in this post can be found in the RxJs Explained In Plain English Git Repository.

注意:本文中使用的所有示例都可以在纯英语Git存储库中解释RxJs中找到

术语 (Terminology)

There are several key players in RxJS that you should know

您应该了解RxJS中的几个关键角色

  • Observable — Produces a sequence (stream) of data

    可观察-产生数据序列(流)
  • Observer — consumes Observable values

    观察者-消耗可观察值
  • Subscriber — connects an Observer with an Observable

    订户—将观察者与可观察者连接
  • Operator — en-route value transformations

    运营商-途中价值转换
  • Subject — includes both an Observable and Observer

    主题-包括可观察者和观察者

Note: I’m not going to dive into Subjects in this post. There are different types of Subjects and quite a bit to cover so that’ll be in a different post.

注意:我不会在本文中深入探讨主题。 有不同类型的主题,涉及的内容很多,因此将出现在不同的帖子中。

Netflix类比 (The Netflix Analogy)

All of these terms can be quite daunting to understand at first so lets work through an analogy to better understand what each players role is in the grand scheme of things.

所有这些术语起初要理解起来可能很艰巨,因此让我们做一个类比以更好地了解每个参与者在总体方案中所扮演的角色。

Netflix is a content Producer. The company has a website and a mobile app that makes their content Observable. I become a Subscriber to the service by creating an account and once I subscribe to Netflix my family can Observe the content they produce.

Netflix是内容制作者。 公司拥有一个网站和移动应用程序,使它们的内容可观察到。 我通过创建一个帐户成为该服务的订阅者订阅Netflix之后,我的家人就可以观察他们制作的内容。

The Observable, in this case the app, can invoke certain actions on the Observer, my family. Those actions are

Observable,在这种情况下为应用程序,可以在我的Observer上调用某些操作。 这些动作是

  • next() — to serve and play the next episode in the stream

    next()—服务和播放流中的下一

  • error() — to notify the Observer when there’s an error

    error()—发生错误时通知观察者

  • complete() — to notify the Observer when the season or series is complete

    complete()—当季节或系列结束时通知观察者

As a Subscriber I have to provide an Observer, someone to watch the content, to the Observable so that the Observable can invoke the next(), error() and complete() methods on the Observer.

作为订阅者,我必须向Observable提供一个Observer,供观看者观看内容,以便Observable可以在Observer上调用next()error()complete()方法。

Keeping the Netflix analogy in mind, an Observable has the following responsibilities

牢记Netflix的类比,Observable具有以下职责

  • Allow subscribing and unsubscribing to its stream

    允许订阅取消订阅其流

  • Emit the next value to the Observer

    下一个值发送给观察者

  • If something goes wrong, notify the Observer about the error

    如果出现问题,请通知观察员有关错误

  • And notify the Observer when the stream is complete

    并在流完成时通知观察者

An Observer, on the other hand, can decide how to

另一方面,观察员可以决定如何

  • handle the next value from the Observable

    处理来自Observable的下一个

  • handle any errors emitted from the Observable

    处理从Observable发出的任何错误

  • handle when the Observable says that the data stream is complete

    当Observable说数据流完成时处理

by providing a function for each one.

通过为每个提供一个功能。

If we were to visualize this in a diagram this is what it would look like

如果我们在图表中将其可视化,它将是这样

An Observable pushes data to the Observers that are Subscribed to the data stream
A diagram explaining the relation between Observable, Subscribers and Observers
解释可观察者,订阅者和观察者之间关系的图

使用RxJ创建可观察对象(Creating an Observable Using RxJs)

In this section we’ll be looking at a few methods RxJs provides to create an Observable. I’ll list them out first and then we’ll dive into the code.

在本节中,我们将研究RxJs提供的几种创建Observable的方法。 我将首先列出它们,然后我们将深入研究代码。

  • from()

    从()
  • Observable.create() or (new Observable(fn))

    Observable.create()或( new Observable(fn) )

  • of()

    的()

But before we jump into making an Observable lets take a quick look at what an Observer looks like first.

但是,在我们开始制作Observable之前,让我们先快速了解一下Observer的外观。

As mentioned above, the Observer chooses how to handle the next(), error() and complete() methods that are invoked by the Observable.

如上所述,观察者选择如何处理由Observable调用next()error()complete()方法。

An Observer should be able to handle the next(), error() and complete() methods that can be invoked by the Observable.
Example of a simple Observer that handles the next(), error() and complete() methods
处理next(),error()和complete()方法的简单Observer的示例

Note: It’s not necessary to implement all three methods in the Observer. At the very least, an Observer should be able to handle the next method.

注意:不必在Observer中实现所有三种方法。 至少,观察者应该能够处理next方法。

from()函数 (The from() function)

This method is capable of converting a variety of things into an Observable. This includes but is not limited to Arrays, Promises and iterables.

此方法能够将各种事物转换为Observable。 这包括但不限于数组,承诺和可迭代对象。

The from() function is capable of converting an array into an Observable.
Example of how to use from() to convert an Array into an Observable.
如何使用from()将数组转换为Observable的示例。

Note: In the example above I’ve explicitly defined an Observer object that implements the next(), error() and complete() methods and passed it to the subscribe method. RxJs also allows us to pass these as functions directly into the subscribe method.

注意:在上面的示例中,我明确定义了一个Observer对象,该对象实现next() error()complete()方法,并将其传递给subscription方法。 RxJs还允许我们将这些作为函数直接传递给subscription方法。

Consider the following.

考虑以下。

The subscribe() method can also take three functions as parameters that each handle the next(), error() and complete() method
Example showing the subscribe method of an Observable taking functions as arguments.
该示例显示以函数为参数的Observable的subscription方法。

When working with Promises, the from() function returns an Observable that emits the Promise’s resolved value. If the Promise is resolved, then the resolved value is emitted from the Observable otherwise the rejection error from the Promise is emitted.

使用Promises时, from()函数返回一个Observable,它发出Promise的已解析值。 如果已解决Promise,则从Observable发出已解决的值,否则将发出Promise的拒绝错误

Image for post
Example of using the from() function to handle Promises as an Observable
使用from()函数将Promises作为Observable处理的示例

Observable.create()(Observable.create())

The create() method takes a function as a parameter and converts it to an Observable. This function gets executed every time an Observer subscribes to that Observable. The function parameter is called onSubscription.

create()方法将函数作为参数并将其转换为Observable。 每当观察者订阅该Observable时,都会执行此函数。 函数参数称为onSubscription

In essence, this allows us to define what will happen when an Observer subscribes to this Observable. This then makes it our responsibility to invoke the next(), error() and complete() methods of the Observer inside the onSubscription function.

从本质上讲,这使我们能够定义当观察者订阅此Observable时将发生的情况。 这样,我们就有责任在onSubscription函数内部onSubscription Observer的next()error()complete()方法。

The onSubscription function is called with the Observer as its only parameter.

使用Observer作为唯一参数调用onSubscription函数。

Note: The create() method is deprecated and you should use the new Observable() constructor instead. In the following example I use the new Observable() constructor but in the code files you can see the use of Observable.create().

create()方法已经过时,你应该使用new Observable()构造函数来代替。 在下面的示例中,我使用了new Observable()构造函数,但是在代码文件中,您可以看到Observable.create()的用法

The constructor lets us create an Observable manually. It takes a function parameter and called when an Observer subs to it
Example of creating an Observable manually using the constructor method.
使用构造方法手动创建Observable的示例。

of()函数 (The of() function)

This function takes any number of arguments and returns an Observable that emits each argument as an observable sequence.

此函数接受任意数量的参数,并返回一个Observable,该对象将每个参数作为可观察序列发出。

const { of } = require('rxjs');of(1, 2, 3).subscribe(data => console.log(data));

Note: I gave a pretty simple example here that can also be found in the RxJs docs. Later in the post you’ll see more ways of using this.

注意:我在这里给出了一个非常简单的示例,也可以在RxJs文档中找到该示例。 在文章的后面,您将看到更多使用此方法的方法。

In this section we covered how to create an Observable using three different methods. Of course there are more ways that we didn’t cover here but feel free to browse the RxJs Docs. You can find them under the Creation Operators heading.

在本节中,我们介绍了如何使用三种不同的方法创建一个Observable。 当然,这里有很多我们没有介绍的方法,但是可以随意浏览RxJs Docs 。 您可以在“创建运算符”标题下找到它们。

In the next section we’ll look at the most commonly used Operators that RxJs provides.

在下一节中,我们将介绍RxJs提供的最常用的运算符。

RxJs运算符 (RxJs Operators)

… are just functions.

……只是功能。

Nothing more than that.

仅此而已。

They’re functions with a clearly defined input and output. An Operator takes an Observable as an input and produces an Observable as output. They act as a transforming function that transforms the data passing through them.

它们具有明确定义的输入和输出功能。 运算符将Observable作为输入,并产生Observable作为输出。 它们充当转换功能,可转换通过它们的数据。

Take the Array class as an example, it has a built in method called map(). This method takes a function as a parameter and returns a new array with the transformed values.

以Array类为例,它具有一个称为map()的内置方法。 此方法以函数为参数,并返回带有转换后值的新数组。

Similarly, RxJs provides an Operator called map(). Like the map() method from Arrays, this too takes a function as a parameter but the Operator returns an Observable that you can then subscribe to.

同样,RxJs提供了一个称为map()的运算符。 就像Arrays中的map()方法一样,它也将一个函数作为参数,但是运算符返回一个Observable,然后可以对其进行订阅。

There are two types of Operators

有两种类型的运算符

  • Creation Operators — used to create a new Observable. These are what we covered in the first section of this post.

    创建运算符-用于创建新的Observable。 这些是我们在本文第一部分中介绍的内容。

  • Pipeable Operators — used for transforming data in multiple steps. These take an Observable as input and produce an Observable as output. They’re pure functions. Which means that the previous Observable remains unmodified.

    管道运算符-用于分多个步骤转换数据。 它们将一个Observable作为输入,并产生一个Observable作为输出。 它们是纯函数。 这意味着先前的Observable保持不变。

There are a ton of Operators available in RxJs but there are a few that you may end up using more often.

RxJ中有大量的运算符可用,但您最终可能会经常使用其中一些运算符。

Here are the 7 Operators that you may use and see more often:

这是您可能会使用并经常看到的7个运算符:

  • map

    地图
  • filter

    过滤
  • reduce

    减少
  • concat

    康卡特
  • merge

    合并
  • mergeMap

    mergeMap
  • switchMap

    switchMap

map(),filter()和reduce()运算符 (The map(), filter() and reduce() Operators)

If you’ve worked with Arrays in the past these operators probably sound really familiar. They work in the exact same way, but in the case of Operators each one is returning an Observable.

如果您过去曾经使用过Arrays,那么这些运算符可能听起来真的很熟悉。 它们的工作方式完全相同,但是对于Operators,每个人都返回一个Observable。

Consider the following

考虑以下

Image for post
Example of how to use the map(), filter() and reduce() Operators in RxJs
如何在RxJs中使用map(),filter()和reduce()运算符的示例

concat()和merge()运算符(The concat() and merge() Operators)

… both do the same thing.

……两者都做同样的事情。

They both return an Observable that emits values from every given input Observable.

它们都返回一个Observable,该Observable从每个给定的输入Observable发出值。

The key difference between the two is how each one emits values. The how is what will dictate which one you use for your different use cases.

两者之间的主要区别是每个人如何发出值。 如何确定如何使用您的不同用例。

concat joins multiple Observable together and emits their values sequentially.

concat将多个Observable连接在一起,并顺序发出它们的值。

Image for post
Example of how to use the concat() Operator using RxJs
如何使用RxJs使用concat()运算符的示例

merge joins multiple Observable together and emits their values concurrently.

merge将多个Observable连接在一起,并同时发出它们的值。

Image for post
Example of how to use the merge() Operator using RxJs
如何使用RxJs使用merge()运算符的示例

mergeMap()运算符(The mergeMap() Operator)

A.K.A the flatMap() Operator allows us to flatten nested Observable.

又名, flatMap()运算符使我们可以展平嵌套的Observable。

Lets continue with our Netflix analogy.

让我们继续我们的Netflix类比。

You have multiple seasons of a series that are Observable. Within each season you have 10 episodes that are also Observable. The 10 episodes in this case are nested Observable within each season.

您有一系列可观察的季节。 在每个季节中,您都有10也可以观察到。 在这种情况下,这10个情节在每个季节都嵌套可观察。

To watch the entire series, you first have to select (subscribe to) season one. Then you have to select (subscribe to) each episode one by one and watch through it.

要观看整个系列,您首先必须选择(订阅)第一季。 然后,您必须一个接一个地选择(订阅)每个情节,并逐一观看。

This is what we’d have to do if we weren’t using the mergeMap Operator. We’d have to have nested subscriptions in order to get through the entire show.

如果不使用mergeMap运算符,这就是我们要做的。 我们必须具有嵌套订阅才能浏览整个节目。

Consider the following (without using mergeMap)

考虑以下内容(不使用mergeMap )

Image for post
Example of nested subscriptions when not using mergeMap
不使用mergeMap时的嵌套订阅示例

Here’s the key take away from the code above:

这是上面代码的关键:

/**
* Without using mergeMap() we'd need to have nested subscriptions
* to get through the entire series.
*/const TheLastKingdom$ = getAllEpisodesForThisSeries();// captures one season at a time
TheLastKingdom$.subscribe(seasons => {
let currentSeason = '';

seasons.subscribe(episode => {
// Goes through all episodes before going to the next season console.log(episode);
currentSeason = episode.season;
});

console.log(`End of ${currentSeason}...\n`)
});

The mergeMap Operator allows us to flatten the nested Observable so we wouldn’t need nested subscriptions.

mergeMap运算符允许我们展平嵌套的Observable,因此我们不需要嵌套的订阅

In our analogy, mergeMap will allow us to have a seamless experience where each episode would play one after the other without you having to select (subscribe to) the next season.

以我们的类比, mergeMap将使我们拥有无缝的体验,其中每个情节都可以接连播放,而无需您选择(订阅)下一季。

Everything in the code above remains the same. The last part would now look like this when using the mergeMap Operator.

上面代码中的所有内容保持不变。 现在,使用mergeMap运算符时,最后一部分看起来像这样。

const TheLastKingdom$ = getAllEpisodesForThisSeries();TheLastKingdom$
.mergeMap(seasons => seasons)
.subscribe(episode => console.log(episode));

This is how the official documentation of the mergeMap Operator describes it:

这是mergeMap Operator的官方文档描述它的方式:

Returns an Observable that emits items based on applying a function that you supply to each item emitted by the source Observable, where that function returns an Observable, and then merging those resulting Observables and emitting the results of this merger.

返回一个Observable,它基于将您提供的函数应用于源Observable发出的每个项目而发出项目,该函数返回Observable,然后合并这些结果Observables并发出此合并的结果。

switchMap()运算符 (The switchMap() Operator)

Still watching Netflix?

还在看Netflix吗?

Good.

好。

Lets continue with the analogy.

让我们继续类比。

You go to the search page and search for a title you want to watch. The app sends off a request to the server to get the details for that title. Now, you’re waiting for the response to come back but it’s taking too long. This could be a network issue on your end or something’s taking longer on Netflix’s end.

您转到搜索页面并搜索要观看的标题。 该应用向服务器发送请求,以获取该标题的详细信息。 现在,您正在等待响应返回,但是花费的时间太长。 这可能是您的网络问题,也可能是Netflix花费了更长的时间。

Whatever the case may be, you lose you patience and search for another title. This one comes back right away. You’re reading through the description and all of a sudden the title you searched for first abruptly appears on the screen.

无论如何,您都会失去耐心并寻找另一个标题。 这个马上回来。 您正在阅读说明,突然间,您首先搜索的标题突然出现在屏幕上。

Your experience, is ruined.

您的经验,毁了。

What happened? Why did the first title come back and get displayed even though you don’t care about it anymore?

发生了什么? 即使您不再关心第一个标题,为什么它又回来显示?

Well, the first request you made never got canceled. For whatever reason it just took longer to respond. And once it responded, the browser showed what came through.

好吧,您发出的第一个请求从未被取消。 无论出于什么原因,它都花了更长的时间做出回应。 一旦响应,浏览器就会显示出结果。

To remediate issues of this nature you’d use the switchMap Operator. Lets have a look at what that would look like.

要纠正此类问题,您可以使用switchMap运算符。 让我们来看看会是什么样子。

Image for post
Example of using the switchMap Operator in RxJs
在RxJs中使用switchMap运算符的示例

Here’s how it works.

运作方式如下。

The source observable, in this case showNames$, emits the name of each show on a one second interval. The inner observable, getSearchedShowDetails$, simulates an HTTP request to get the details of the show by adding a random delay before returning the response.

可观察的源(在这种情况下为showNames$以一秒钟的间隔发出每个节目的名称。 内部可观察的getSearchedShowDetails$模拟HTTP请求,通过在返回响应之前添加随机延迟来获取节目的详细信息。

If the source observable changes before the inner observable gets the response, then the inner observable will stop emitting items from the earlier request and will start emitting items from the new one.

如果源可观察对象内部可观察对象获得响应之前发生更改,则内部可观察对象将停止发出较早请求中的项目,并开始从新请求中发出项目。

So this mean that if getSearchedShowDetails$ takes longer than one second to respond, then the details of that show won’t be emitted. And anything returned less than or exactly in one second will be emitted.

因此,这意味着,如果getSearchedShowDetails$花费的时间超过一秒钟,则不会显示该节目的详细信息。 返回不到一秒或恰好在一秒钟内返回的所有内容。

Here’s what the output of the code above will look like.

上面的代码输出如下所示。

Image for post
Example of the output from the switchMap() operator code
switchMap()操作员代码的输出示例

The last value emitted in this case would take the full three seconds to respond. That’s because the source observable didn’t change its value during that time.

在这种情况下发出的最后一个值将花费整整三秒钟的时间进行响应。 这是因为可观察的源在此期间未更改其值。

Note: The output may not be the same when you run the code in the switchMap_operator.js file due to the random delays in the getSearchedShowDetails$ function.

注意:由于getSearchedShowDetails$函数中的随机延迟,当您运行switchMap_operator.js文件中的代码时,输​​出可能会不同

结论 (Conclusion)

Well, that’s all for this post.

好,这就是这篇文章的全部。

You should now have a good understanding of

您现在应该对

  • the terminology used in RxJs

    RxJ中使用的术语
  • the roles that an Observer, Observable, Subscriber and Operator play and their responsibilities

    观察者,可观察者,订阅者和操作者所扮演的角色及其职责
  • how to create an Observable using various methods.

    如何使用各种方法创建一个Observable。
  • a few of the most often used operators and how they work

    一些最常用的运算符及其工作方式

There’s still a lot more to cover in the land of RxJs but this should get you up and running with what’s going on.

RxJ领域还有很多要涵盖的内容,但这应该可以使您开始并运行正在发生的事情。

Until next time, peace ✌️

直到下次,和平peace️

Be sure to check out part two of this post which covers error handling.

一定要检查这篇文章的第二部分,其中涵盖了错误处理。

翻译自: https://medium.com/javascript-in-plain-english/rxjs-explained-in-plain-english-9d2daa329f34

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值