rxjs angular
In this tutorial, we'll learn to use the RxJS 6 library with Angular 6 or Angular 7. We'll learn about:
在本教程中,我们将学习将RxJS 6库与Angular 6或Angular 7结合使用。我们将了解:
How to import and call operators and chain them with the pipe()
function.
如何导入和调用运算符以及如何使用pipe()
函数将它们链接在一起。
Finally we'll see how to use some popular pipeable operators such as tap()
, map()
and filter()
and their new import paths in RxJS 6.
最后,我们将了解如何在RxJS 6中使用一些流行的可管道运算符,例如tap()
, map()
和filter()
以及它们的新导入路径。
Note: This tutorial works with both Angular 6 and Angular 7.
注意 :本教程适用于Angular 6和Angular 7。
Throughout this tutorial, we’ll start looking at what reactive programming, asynchronous operations and data streams are and how they are related to the RxJS library. We’ll then see the concept of an RxJS Observable
with examples, the various types of Observables such as:
在整个教程中,我们将开始研究什么是React式编程,异步操作和数据流,以及它们与RxJS库的关系。 然后,我们将通过示例,各种类型的Observable来了解RxJS Observable
的概念,例如:
Subject
,
Subject
,
BehaviorSubject
and ReplaySubject
,
BehaviorSubject
和ReplaySubject
,
Next, we’ll see what RxJS operators are and examples of some popular operators such as tap()
, map()
, filter()
, share()
, etc. And finally we’ll see how Angular uses the RxJS Observable to do asynchronous programming.
接下来,我们将看到RxJS运算符是什么,以及一些流行的运算符的示例,例如tap()
, map()
, filter()
, share()
等。最后,我们将了解Angular如何使用RxJS Observable来进行操作异步编程。
Let’s see the definition of Reactive programming from different sources.
让我们看看来自不同来源的React式编程的定义。
This is how Andre Staltz, the creator of cycle.js (A functional and reactive JavaScript framework for predictable code) defines it:
这就是cycle.js (可预测代码的功能性和React性JavaScript框架)的创建者Andre Staltz定义它的方式:
Reactive Programming is programming with asynchronous data streams
React式编程是使用异步数据流进行编程
This means when you are writing code that deals with asynchronous operations and streams of data, you are doing reactive programming.
这意味着当您编写处理异步操作和数据流的代码时,您正在执行React式编程。
Now, this is the definition from Wikipedia which is more in-depth:
现在,这是来自维基百科的更深入的定义:
In computing, reactive programming is a declarative programming paradigm concerned with data streams and the propagation of change.
在计算中,React式编程是与数据流和变化的传播有关的声明式编程范例。
This means reactive programming is a declarative (vs. a procedural) style of programming that works on streams of data.
这意味着响应式编程是一种声明式(相对于过程式)的编程风格,适用于数据流。
For a detailed guide on reactive programming and data streams, check out: The introduction to Reactive Programming you've been missing.
有关React式编程和数据流的详细指南,请查看: 您缺少关于React式编程的介绍 。
What is Stream
什么是流
A stream is an essential concept in reactive programming so it's worth seeing the definition before we proceed further.
在响应式编程中,流是必不可少的概念,因此在继续进行之前,有必要先看一下定义。
In all definitions we’ve seen the word stream.
在所有定义中,我们都看到了词流。
So what is a stream?
那么什么是流?
Simply put:
简单的说:
A stream refers to values of data overtime.
流是指数据超时的值。
We'll see later that Observables and streams are very related concepts.
稍后我们将看到Observable和流是非常相关的概念。
Now, that we’ve seen the conceps of reactive programming and data streams, let’s see what RxJS is.
现在,我们已经看到了React式编程和数据流的概念,让我们看看RxJS是什么。
RxJS is a popular library among web developers. It provides functional and reactive programming patterns for working with events and streams of data and has been integrated in many web development libraries and frameworks such as Angular.
RxJS是Web开发人员中流行的库。 它提供了用于处理事件和数据流的功能性和React性编程模式,并且已集成到许多Web开发库和框架(例如Angular)中。
RxJS makes it easy for JavaScript developers to write asynchronous code using composable Observables instead of callbacks and Promises.
RxJS使JavaScript开发人员可以轻松地使用可组合的Observable而不是回调和Promises编写异步代码。
RxJS stands for Reactive Extensions for JavaScript and it actually has implementations in other programming languages such as Java, Python, Ruby, and PHP etc. It's also available for platforms such as Android. Check out the complete list of supported languages and platforms.
RxJS代表JavaScript的Reactive Extensions,它实际上具有其他编程语言(例如Java,Python,Ruby和PHP等)的实现。它也可用于Android等平台。 查看支持的语言和平台的完整列表 。
RxJS v6 is currently the stable version of RxJS and it has many breaking changes with RxJS v5. You can check out more information about the changes and how to migrate from the old version from this official migration guide.
RxJS v6当前是RxJS的稳定版本,并且在RxJS v5中有许多重大更改。 您可以从本官方迁移指南中查看有关更改以及如何从旧版本进行迁移的更多信息。
RxJS 6 has many advantages over the previous RxJS 5 version(s), such as:
与以前的RxJS 5版本相比,RxJS 6具有许多优点,例如:
RxJS 6 Observable follows the Observable Spec Proposal,
RxJS 6 Observable遵循Observable Spec Proposal ,
RxJS is a JavaScript library which means you can install it in the same way you install other libraries:
RxJS是一个JavaScript库,这意味着您可以使用与安装其他库相同的方式来安装它:
Using RxJS with ES6 via npm
通过npm在ES6中使用RxJS
In your project, you can run the following command to install RxJS:
在您的项目中,您可以运行以下命令来安装RxJS:
$ npm install rxjs
You can then import the symbols you want to use from the rxjs
package or a sub-package such as rxjs/operators
:
然后,您可以从rxjs
包或子包(例如rxjs/operators
导入要使用的符号:
import { Observable, Subscriber } from 'rxjs';
import { tap, map, filter } from 'rxjs/operators';
We imported the Observable
and Subscriber
symbols from rxjs
and the tap
, map
and filter
operators from rxjs/operators
.
我们从rxjs
导入了Observable
和Subscriber
符号,并从rxjs/operators
导入了tap
, map
和filter
运算rxjs/operators
。
We'll see later what these symbols are and how to use them in your Angular application.
稍后我们将看到这些符号是什么以及如何在Angular应用程序中使用它们。
Using RxJS from a CDN
从CDN使用RxJS
You can also use RxJS from a CDN using a <script>
in your HTML document:
您还可以使用HTML文档中的<script>
从CDN使用RxJS:
<script src="https://unpkg.com/rxjs/bundles/rxjs.umd.min.js"></script>
Note: Please note that in Angular 6 & 7, RxJS 6 is already included in your project so you don't need to install it manually.
注意 :请注意,在Angular 6和7中,RxJS 6已包含在您的项目中,因此您无需手动安装它。
RxJS uses the concept of Observables to handle and work with asynchronous and event-based code.
RxJS使用Observables的概念来处理和使用基于事件的异步代码。
The asynchronous word comes from Asynchrony. In computer programming, here is the definition of Asynchrony from Wikipedia:
异步字来自异步。 在计算机编程中,这是维基百科中异步的定义:
Asynchrony, in computer programming, refers to the occurrence of events independent of the main program flow and ways to deal with such events. These may be "outside" events such as the arrival of signals, or actions instigated by a program that take place concurrently with program execution, without the program blocking to wait for results.
在计算机编程中,异步是指事件的发生与主程序流以及处理此类事件的方式无关。 这些可能是“外部”事件,例如信号的到来,或与程序执行同时发生的由程序引发的动作,而程序不会阻塞等待结果。
After reading this definition, you may have concluded how much asynchrony is important for computers and programming!
阅读此定义后,您可能已经得出结论,异步对于计算机和编程而言很重要!
Let's make this simple!
让我们简单点吧!
Asynchronous code is the inverse of synchronous code which is the original way of thinking about your code when you are first introduced to programming.
异步代码是同步代码的逆过程,这是您初次接触编程时对代码进行思考的原始方式。
Your code is synchronous when it's running in sequences i.e instruction by instruction in the order they appear in the source code.
当您的代码按顺序运行时,即按它们在源代码中出现的顺序逐条指令运行时,它们是同步的。
For example, let's consider this simple JavaScript code:
例如,让我们考虑以下简单JavaScript代码:
const foo = "foo" //1
const bar = "bar" //2
const foobar = foo + bar //3
console.log(foobar) //4
The browser will run this synchronous code line by line from line 1 to 4 starting by assigning the foo
and bar
variables, concatenating them and displaying the foobar
variable in the console.
浏览器将从第1行到第4行逐行运行此同步代码,首先分配foo
和bar
变量,将它们连接起来并在控制台中显示foobar
变量。
JavaScript supports also the asynchronous approach of writing code which makes sense, since you need to respond to the user events in the browser but you don't actually know when the user interacts with your application (and in which order) when you are writing code.
JavaScript还支持有意义的异步代码编写方法,因为您需要在浏览器中响应用户事件,但实际上您不知道用户何时在与您的应用程序交互(以及顺序如何) 。
This was originally achieved using callbacks which you need to define in your code and specify when they will be called.
这最初是使用回调实现的,您需要在代码中定义这些回调并指定何时调用它们。
For example, the following asynchronous code will display You clicked the button! when the user clicks the button identified by the mybutton
identifier:
例如,以下异步代码将显示您单击了按钮! 当用户单击由mybutton
标识符标识的按钮时:
document.getElementById('mybutton').addEventListener('click', () => {
console.log("You clicked the button!")
})
The second argument of the addEventListener()
method is the callback.
addEventListener()
方法的第二个参数是回调。
You can also use callbacks to handle asynchronous operations which don't involve the DOM. For example, the following code can be used to send an HTTP POST request to a web server:
您还可以使用回调来处理不涉及DOM的异步操作。 例如,以下代码可用于将HTTP POST请求发送到Web服务器:
const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
xhr.status === 200 ? console.log(xhr.responseText) : console.error('error')
}
}
xhr.open('POST', 'your.server.com')
xhr.send()
This is how you perform the famous Ajax calls in JavaScript.
这就是在JavaScript中执行著名的Ajax调用的方式。
Actually, Ajax itself stands for Asynchronous JavaScript and XML.
事实上, 阿贾克斯本身代表的同步ĴavaScript 一个次X ML。
Note: Sending HTTP requests (which is a common operation in web apps) is an asynchronous operation by nature since the request will take time to reach the server which will then send a response back to your client application. In this mean time, the application needs to respond to other actions and perform other tasks and only process the server response when it's received.
注意 :发送HTTP请求(这是Web应用程序中的常见操作)本质上是异步操作,因为请求将花费一些时间到达服务器,然后服务器将响应发送回客户端应用程序。 同时,应用程序需要响应其他操作并执行其他任务,并且仅在收到服务器响应后才对其进行处理。
If you have ever extensively worked with callbacks, you'll notice one problem with them. They are difficult to track!
如果您曾经广泛使用过回调,您会发现它们存在一个问题。 他们很难追踪!
When you write complex applications you usually end up writing nested callbacks (callbacks inside callbacks) with multiple nesting levels. This is what's known as the callback hell.
当您编写复杂的应用程序时,通常最终会编写具有多个嵌套级别的嵌套回调(回调内部的回调)。 这就是所谓的回调地狱 。
Modern JavaScript introduced other approaches or abstractions to deal with asynchronous operations (without using too much callbacks) such as Promises and Async/Await.
现代JavaScript引入了其他方法或抽象来处理异步操作(不使用过多的回调),例如Promises和Async / Await。
Promises have been introduced in ES6 (JS 2015).
在ES6 (JS 2015)中引入了承诺。
Async/await has been introduced in ES8 (JS 2017) and it's actually a syntactic sugar on top of Promises which helps developers write asynchronous code with Promises in a way that looks synchronous.
Async / await已在ES8(JS 2017)中引入,它实际上是Promises之上的语法糖,它可以帮助开发人员以看上去同步的方式使用Promises编写异步代码。
But Promises are actually similar to callbacks and have the same nesting problem at some degree.
但是Promises实际上类似于回调,并且在某种程度上具有相同的嵌套问题。
Since developers are always looking for better solutions we now have Observables which use the observer software pattern.
由于开发人员一直在寻找更好的解决方案,因此我们现在有了使用观察者软件模式的Observables。
The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. Observer pattern.
观察者模式是一种软件设计模式,其中一个称为主题的对象会维护其依赖者的列表(称为观察者),并通常通过调用其方法之一来自动将状态更改通知他们。 观察者模式 。
Observables are implemented in the ReactiveX project which has implementations in various languages. RxJS is the JavaScript implementation.
可观察对象在ReactiveX项目中实现,该项目具有各种语言的实现。 RxJS是JavaScript实现。
Note: Observables are implemented in many other libraries such as zen-observable and xstream but RxJS Observables are the most popular in JavaScript.
注意 :Observables在许多其他库中实现,例如zen-observable和xstream,但是RxJS Observables在JavaScript中最受欢迎。
Observables are not yet a builtin feature of JavaScript but there is a proposal to add them in EcmaScript.
可观察对象还不是JavaScript的内置功能,但是建议将其添加到EcmaScript中。
Now, what's an RxJS Observable?
现在,什么是RxJS Observable?
An Observable is an entity that emits (or publishes) multiple data values (stream of data) over time and asynchronously.
一个Observable是一个实体,它随时间推移并异步地发出(或发布)多个数据值(数据流)。
This is the definition of an Observable from the RxJS docs
这是RxJS文档中 Observable的定义
Observable represents the idea of an invokable collection of future values or events.
可观察表示未来值或事件的可调用集合的想法。
Observers and Subscriptions
观察者和订阅
There are also related concepts that you'll work with when using Observables which are Observers and Subscriptions.
使用Observable( 观察者和订阅)时,还需要处理一些相关概念。
Observers are also called listeners (or consumers) as they can listen or subscribe to get the observed data.
观察者也称为侦听器(或使用者),因为他们可以侦听或订阅以获取观察到的数据。
From the RxJS docs:
从RxJS文档中:
Observer is a collection of callbacks that knows how to listen to values delivered by the Observable.
Observer是一组回调,它们知道如何侦听Observable传递的值。
Subscriptions are objects that are returned when you subscribe to an Observable. They contain many methods such as the unsubscribe()
method that you can call to unsubscribe from receving published values from the Observable.
订阅是您订阅Observable时返回的对象。 它们包含许多方法,例如unsubscribe()
方法,您可以调用这些方法来取消订阅以从Observable中检索发布的值。
From the official docs:
从官方文档:
Subscription represents the execution of an Observable, is primarily useful for cancelling the execution.
订阅表示Observable的执行,主要用于取消执行。
A Subject is a special type of Observable that observers can also subscribe to it to receive published values but with one difference: The values are multicasted to many Observers.
主题是Observable的一种特殊类型,观察者也可以订阅它以接收已发布的值,但有一个区别: 值被多播到许多Observers上 。
Note: By default an RxJS Observable is unicast.
注意 :默认情况下,RxJS Observable是单播的。
Unicast simply means that each subscribed observer has an independent execution of the Observable while multicast means that the Observable execution is shared by multiple Observers.
单播仅表示每个订阅的观察者对Observable具有独立的执行,而多播则意味着多个观察者共享Observable的执行。
Note: Subjects are similar to Angular EventEmitters.
注意 :主题类似于Angular EventEmitters。
So when using Subjects instead of plain Observables, all subscribed Observers will get the same values of emitted data.
因此,当使用Subject而不是普通Observable时,所有订阅的Observer都将获得相同的发射数据值。
Note: Subjects are also Observers i.e they can also subscribe to other Observables and listen to published data.
注意 :主题也是观察者,即他们也可以订阅其他可观察对象并收听发布的数据。
Hot and Cold Observables
冷热观测
Unlike regular Observables, Subjects are called hot. A hot Observable starts emitting events even before any observer subscribes to it which means observers may lose previous emitted values if they don’t subscribe at that right time while cold Observables ****start emitting values when at least one observer is subscribed.
与常规的Observables不同,Subject被称为hot 。 一个热的Observable甚至在任何观察者订阅之前就开始发出事件,这意味着如果观察者在正确的时间不进行订阅,则观察者可能会丢失先前发出的值,而冷的 Observable则在至少一个观察者被订阅时才开始发出值。
Note: You can use the asObservable()
method to convert a subject to only an Observable.
注意 :可以使用asObservable()
方法将主题转换为仅可观察的对象。
BehaviorSubject
和ReplaySubject
(RxJS’ BehaviorSubject
and ReplaySubject
)RxJS provides two other types of Subjects: BehaviorSubject
and ReplaySubject
.
RxJS提供了另外两种类型的主题: BehaviorSubject
和ReplaySubject
。
With a normal Subject, Observers that are subscribed at a point later will not receive data values emitted before their subscriptions. In many situations, this is not the desired behavior we want to implement. This can be solved using BehaviorSubject
and ReplaySubject
.
对于普通主题,稍后在某个点订阅的观察者将不会接收在订阅之前发出的数据值。 在许多情况下,这不是我们想要实现的期望行为。 可以使用BehaviorSubject
和ReplaySubject
解决。
ReplaySubject
works by using a buffer that keeps the emitted values and re-emit them when new Observers are subscribed.
ReplaySubject
通过使用缓冲区来工作,该缓冲区保留发出的值并在订阅新的Observer时重新发射它们。
BehaviorSubject
works like ReplaySubject
but only re-emits the last emitted value.
BehaviorSubject
工作方式类似于ReplaySubject
但仅重新发出最后发出的值。
You can create an RxJS Observable using the Observable.create()
method which takes a function with an observer
argument. You can then subscribe to the returned Observable instance.
您可以使用Observable.create()
方法创建RxJS Observable,该方法采用带有observer
参数的函数。 然后,您可以订阅返回的Observable实例。
There many other methods to create Observables besides the static create()
method:
除了静态create()
方法之外,还有许多其他方法可以创建Observables:
The lift()
instance method which creates a new Observable from the instance (the source) it's called on,
lift()
实例方法,可从调用该实例的实例(源)创建一个新的Observable,
The of([])
operator which creates an Observable of a single value. We'll see an example next,
of([])
运算符,它创建单个值的Observable。 接下来,我们将看一个示例,
The interval(interval)
operator which creates an Observable that emits an infinite sequence of numbers. Each number is emitted at a constant interval of time in seconds,
创建一个Observable的interval(interval)
运算符发出一个无穷大的数字序列。 每个数字都会以固定的时间间隔(以秒为单位)发出,
The timer() operator which returns an Observable that after a specified amount of time, emits numbers in sequence every specified duration,
timer()运算符,它返回一个Observable,在指定的时间量后,它在每个指定的持续时间内依次发出数字,
The from()
method that creates an Observable from a Promise or an array of values,
from()
Promise或值数组创建Observable的from()
方法,
The fromEvent()
method that creates an Observable from a DOM event,
从DOM事件创建Observable的fromEvent()
方法,
The ajax()
method which creates an Observable that sends an Ajax request.
创建一个发送一个Ajax请求的Observable的ajax()
方法。
We'll see these creation methods by example later.
我们将在后面的示例中看到这些创建方法。
After creating an Observable
, you can subscribe to it using the subscribe()
method on the instance which returns an instance of Subscription
.
创建Observable
,可以在实例上使用Subscription
subscribe()
方法对其进行预订,该方法返回Subscription
的实例。
Let's now see a simple example of creating and working with an Observable.
现在,让我们看一个创建和使用Observable的简单示例。
First let's create an Observable:
首先让我们创建一个Observable:
let ob$ = Observable.create((observer) => {
observer.next("A new value!");
});
We create an ob$
Observable and we define the logic that our Observable is supposed to do in the body of the passed in method.
我们创建一个ob$
Observable,然后在传入的方法的主体中定义Observable应该执行的逻辑。
In this example, the Observable will simply emit the A new value! value to the subscribed Observer.
在此示例中,Observable将仅发出A新值! 值给订阅的观察者。
Note: The dollar sign is just a convention for naming variables that hold instance of Observables.
注意 :美元符号只是用于命名包含Observables实例的变量的约定。
We call the next()
method of the observer object to inform it of the available values.
我们调用观察者对象的next()
方法来通知它可用的值。
Note: All observer objects must have a collection of methods such as next()
, complete()
and error()
. This allows Observables to communicate with them.
注意 :所有观察者对象都必须具有方法的集合,例如next()
, complete()
和error()
。 这使Observable可以与它们进行通信。
The next()
method is used by the Observable to pass values (publish values) to the subscribed Observer.
Observable使用next()
方法将值(发布值)传递给订阅的Observer。
Next, let's create an observer object:
接下来,让我们创建一个观察者对象:
let observer = {
next: data => console.log( 'Data received: ', data),
complete: data => console.log('Completed'),
};
An observer is a plain JavaScript object that contains methods such as next()
, complete()
and error()
. This means it knows how to get notified by the Observable.
观察者是一个普通JavaScript对象,其中包含next()
, complete()
和error()
。 这意味着它知道如何通过Observable进行通知。
Note: You can also add other custom attributes and methods to the Observer objects besides next()
, complete()
and error()
.
注意 :除了next()
, complete()
和error()
之外,还可以向Observer对象添加其他自定义属性和方法。
Finally, let's subscribe to our ob$
Observable and return a Subscription
:
最后,让我们订阅我们的ob$
Observable并返回一个Subscription
:
let subscription = ob$.subscribe(observer);
Once you susbscribe to the ob$
Observable, you'll get the following output in the console:
怀疑ob$
Observable后,您将在控制台中获得以下输出:
Data received: A new value!
RxJS provides the implemenation of Observable concept but also a variety of operators that allows you to compose Observables.
RxJS提供了Observable概念的实现,但还提供了多种运算符,使您可以编写Observable。
Operators offer a declarative way to perform complex asynchronous operations with Observables.
运算符提供了一种声明性的方式来使用Observables执行复杂的异步操作。
An operator works on a source Observable by observing its emitted values and applying the intended transformation on them then return a new Observable with the modified values.
操作员通过观察源的发射值并对其进行预期的转换来对源Observable进行操作,然后返回具有已修改值的新Observable。
There many RxJS operators such as:
RxJS运算符很多,例如:
tap()
,
tap()
,
map()
,
map()
,
filter()
,
filter()
,
concat()
,
concat()
,
share()
,
share()
,
retry()
,
retry()
,
catchError()
,
catchError()
,
switchMap()
,
switchMap()
,
and flatMap()
etc.
和flatMap()
等。
RxJS provides two versions of the pipe()
function: A standalone function and a method on the Observable
interface.
RxJS提供了pipe()
函数的两个版本:独立函数和Observable
接口上的方法。
You can use the pipe()
function/method to combine multiple Operators. For example:
您可以使用pipe()
函数/方法来组合多个运算符。 例如:
import { filter, map } from 'rxjs/operators';
const squareOf2 = of(1, 2, 3, 4, 5,6)
.pipe(
filter(num => num % 2 === 0),
map(num => num * num)
);
squareOf2.subscribe( (num) => console.log(num));
The of()
method will create and return an Observable from the 1, 2, 3, 4, 5,6
numbers and the pipe()
method will apply the filter()
and map()
operators on each emitted value.
of()
方法将根据1, 2, 3, 4, 5,6
数字创建并返回一个Observable 1, 2, 3, 4, 5,6
而pipe()
方法将在每个发射值上应用filter()
和map()
运算符。
Angular uses the RxJS Observable as a built-in type for many of its APIs such as:
Angular使用RxJS Observable作为其许多API的内置类型,例如:
The HttpClient
methods return Observables and actual requests are only sent when you subscribe to the returned Observable.
HttpClient
方法返回Observables,只有在您订阅返回的Observable时才发送实际请求。
the [events](https://angular.io/api/router/Router#events)
of the Router instance is an Observable to listen to events on the router.
路由器实例的[events](https://angular.io/api/router/Router#events)
是一个可观察到的事件,用于侦听路由器上的事件。
Also ActivatedRoute
(which contains information about the route associated with the currently loaded component on the router outlet) has many Observable properties such as params
and paramMap
for the route parameters.
另外ActivatedRoute
(包含有关与路由器出口上当前加载的组件关联的路由的信息)也具有许多可观察的属性,例如,用于路由参数的params
和paramMap
。
Let's assume, you have an Angular component and the Router service injected as router
. This example from StackOverflow shows you how you can subscribe to the router events for detecting a route change:
假设您有一个Angular组件,并且将Router服务注入为router
。 StackOverflow的以下示例向您展示了如何订阅路由器事件以检测路由更改:
import { Component } from '@angular/core';
import { Router, Event, NavigationStart, NavigationEnd, NavigationError } from '@angular/router';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
constructor(private router: Router) {
this.router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
console.log("Navigation start");
}
if (event instanceof NavigationEnd) {
console.log("Navigation end");
}
if (event instanceof NavigationError) {
console.log(event.error);
}
});
}
}
The @output()
decorator in a component takes an EventEmitter
instance. EventEmitter
is a subclass of the RxJS Observable.
组件中的@output()
装饰器采用EventEmitter
实例。 EventEmitter
是RxJS Observable的子类。
Angular uses Observables (implemented with the RxJS library) for all asynchronous events. If you are using Angular CLI 6|7, RxJS 6 will be installed by default on your project.
Angular对所有异步事件都使用Observables(由RxJS库实现)。 如果您使用的是Angular CLI 6 | 7,则默认情况下将在项目上安装RxJS 6。
Otherwise you can install it via npm using:
否则,您可以使用以下方法通过npm安装它:
$ npm install rxjs --save
To be able to use the Observable symbol in your code, you first need to import it:
为了能够在代码中使用Observable符号,首先需要将其导入:
import { Observable } from 'rxjs';
This is the new import path in RxJS 6 which is different from RxJS 5.
这是RxJS 6中与RxJS 5不同的新导入路径。
The new Angular HttpClient
works with Observables by default. Methods such as get()
, post()
, put()
and delete()
return an instance of the Observable interface.
默认情况下,新的Angular HttpClient
与Observables一起使用。 get()
, post()
, put()
和delete()
返回Observable接口的实例。
HTTP requests are only sent when we subscribe to the Observable.
仅当我们订阅Observable时才发送HTTP请求。
This is an example of making an HTTP request:
这是发出HTTP请求的示例:
getItems(): Observable<Item[]> {
return this.httpClient.get<Item[]>(this.itemUrl);
}
We assume that you have injected the HttpClient
service as httpClient.
我们假设您已将HttpClient
服务注入为httpClient 。
AsyncPipe
使用Observable
(Using Observable
with AsyncPipe
)Angular AsyncPipe
subscribes to Observable and returns the emitted data. For example. Let's suppose we have this method:
Angular AsyncPipe
订阅Observable并返回发出的数据。 例如。 假设我们有这种方法:
getItems(): Observable {
this.items$ = this.httpClient.get(this.itemUrl);
}
The items$
variable is of type Observable<Item[]>`.
items$
变量的类型为Observable <Item []>`。
After calling the getItems()
method on the component we can use the async
pipe in the component template to subscribe to the returned Observable:
在组件上调用getItems()
方法后,我们可以使用组件模板中的async
管道来订阅返回的Observable:
Observables are used for better support of event handling, asynchronous programming, and handling multiple values. When you define an Observable to publish some values for a consumer, the values are not emitted until you actually subscribe to the Observable.
可观察变量用于更好地支持事件处理,异步编程以及处理多个值。 当您定义一个Observable来为使用者发布一些值时,这些值直到您实际订阅Observable时才会发出。
The Consumer that subscribes to the Observable keeps receiving values until the Observable is completed or the consumer unsubscribes from the observable.
订阅可观察对象的消费者将继续接收值,直到该可观察对象完成或消费者不再订阅该可观察对象。
Let's start by defining an observable that provides a stream of updates
让我们开始定义一个可观察的对象,它提供更新流
map()
运算符 (Using the map()
Operator)The map()
operator is similar to the Array.map()
method. It lets you map observable responses to other values. For example:
map()
运算符类似于Array.map()
方法。 它使您可以将可观察到的响应映射到其他值。 例如:
import { Observable} from 'rxjs';
import { map } from 'rxjs/operators';
getItems(): Observable> {
return this.aService.getItems().pipe(map(response => response.data));
}
The getItems()
method returns an Observable. We're using the map()
operator to return the data
property of the response object.
getItems()
方法返回一个Observable。 我们正在使用map()
运算符返回响应对象的data
属性。
The operator enables us to map the response of the Observable stream to the data
value.
运算符使我们能够将Observable流的响应映射到data
值。
We import the pipeable operator map()
from the rxjs/operators
package and we use the pipe()
method (which takes a variable number of pipeable operators) to wrap the operator.
我们从rxjs/operators
包中导入可管道运算符map()
,并使用pipe()
方法(采用可变数量的可管道运算符)包装该运算符。
filter()
运算符 (Using the filter()
Operator)The filter()
operator is similar to the Array.filter()
method. It lets you filter the observable stream and returns another observable. For example:
filter()
运算符类似于Array.filter()
方法。 它使您可以过滤可观察的流并返回另一个可观察的流。 例如:
import { Observable} from 'rxjs';
import { filter } from 'rxjs/operators';
filter(): Observable<Array<any>> {
return this.aService.getItems()
.pipe(
filter(response => response.code === 200));
}
We use the filter()
operator to only emit a notification to observers of the observable stream when the status code of the HTTP response is 200.
当HTTP响应的状态码为200时,我们使用filter()
运算符仅向可观察流的观察者发出通知。
In this tutorial, you have been introduced to reactive programming, data streams and RxJS 6.
在本教程中,向您介绍了React式编程,数据流和RxJS 6。
You have learned that reactive programming is about coding with asynchronous data streams and that RxJS is the most popular implementation that implements Observables and the observer pattern.
您已经了解到,React式编程是关于使用异步数据流进行编码,并且RxJS是实现Observables和观察者模式的最流行的实现。
You have learned what an Observable is — An object that emits or publishes values over time and asynchronously.
您已经了解了什么是Observable-随时间推移以异步方式发出或发布值的对象。
You have learned about the related concepts to Observables such as Observers and Subscriptions — Observers are objects that listen and consume values published by an Observable and Subscriptions are the objects returned from the subscribe()
method (They are usually used to unsubscribe the Observer from the Observable).
您已经了解了与Observables相关的概念,例如Observers和Subscriptions-Observers是侦听和使用Observable发布的值的对象,Subscriptions是从subscription subscribe()
方法返回的对象(它们通常用于从Observable取消订阅Observer。可观察到的)。
You have also learned about special types of Observables such as Subjects, behavior Subjects (BehaviorSubject
) and replay Subjects (ReplaySubject
) and also the difference between unicast and multicast Observables. As a reminder a multicast Observable shares its execution between all its Observers.
您还了解了特殊类型的Observable,例如主题,行为主题( BehaviorSubject
)和重播主题( ReplaySubject
),以及单播和多播Observable之间的区别。 提醒一下,多播Observable在其所有观察者之间共享其执行。
You learned about cold and hot Observables — hot refers to when the Obseravble starts publishing values when it’s created even before getting any subscriptions.
您了解了冷的和热的Observables-hot是指Obseravble在创建值时开始发布值的时间,甚至在获得任何订阅之前。
You learned about RxJS operators which are methods that are used to compose Observables and work on their data streams.
您了解了RxJS运算符,它们是用于构成Observable并对其数据流进行处理的方法。
Finally, you learned that Angular 6 & 7 uses RxJS v6 for working with asynchronous operations and APIs (instead of callbacks or Promises) in many of its commonly used modules such as HttpClient
, Router
and ReactiveForms
.
最后,您了解到Angular 6和7在其许多常用模块(例如HttpClient
, Router
和ReactiveForms
)中使用RxJS v6处理异步操作和API(而不是回调或Promises)。
This article was originally posted in techiediaries.
翻译自: https://www.freecodecamp.org/news/angular-rxjs-in-depth/
rxjs angular