RxJS快速入门

发布于2/28/2020 来自:「前端知否」微信公众号

本文介绍RxJS的功能,优点和缺点,以及何时使用RxJS。

RxJS的完整名称是Reactive Extension for Javascript。这是一个JavaScript库,它使用Observables来处理响应式程序,它使编写异步或基于回调,事件的代码更容易。 RxJS可以与其他Javascript库和框架一起使用。 javascript和typescript都支持它。

什么是RxJS?

根据RxJS的官方网站,它被定义为一个库,用于通过使用可观察的序列来组成异步和基于事件的程序。它提供了一种核心类型,即可观察的,附属类型(Observer, Schedulers, Subjects)和受Array#extras启发的运算符(map, filter, reduce, every等),以将异步事件作为集合来处理。

RxJS的功能

在RxJS中,以下概念负责处理异步任务:

可观察对象,通知者(Observable)

Observable是创建观察者并将其添加到期望获取值的源目标的函数,例如单击,dom元素中的鼠标事件或Http请求等。

观察者,订阅者(Observer)

它是一个具有next(),error() 和complete()方法的对象,当它们与可观察对象发生交互时即会被调用,即为示例按钮单击,Http请求等交互。

订阅(Subscription)

创建可观察对象后,要执行可观察对象,我们需要订阅它。它也可以用来取消执行。

运算符 (Operators)

运算符是一个纯函数,它以可观察对象作为输入,而输出也是可观察对象。

主题(Subject)

主题是可以多播(即与许多观察者交谈)的可观察对象。考虑一个带有事件监听器的按钮,每次用户单击按钮时,都会使用addlistener调用附加到事件的函数,类似的功能也适用于主题。

调度程序(Schedulers)

调度程序控制何时启动和通知订阅的执行。

何时使用RxJS?

如果您的项目包含大量异步任务处理,那么RxJS是一个不错的选择。而且在Angular项目中默认使用RxJS, 和项目一起加载。

使用RxJS的优点

以下是使用RxJS的优点:

  • RxJS可以与其他Javascript库和框架一起使用。 javascript和typescript都支持它。Angular,ReactJS,Vuejs,nodejs等项目中都有示例。
  • RxJS在处理异步任务方面是一个很棒的库。RxJS使用可观察对象来处理响应式编程,以处理异步数据调用,回调和基于事件的程序。
  • RxJS提供了大量运算符,包括数学,转换,过滤,实用工具函数,条件,错误处理以及联接组合,这些运算符可与响应式编程一起使用,使工作更轻松。

使用RxJS的缺点

以下是使用RxJS的缺点:

  • 在使用可观察对象的代码中,调试代码有一些难度。
  • 如果使用了Observable,那么要将所有代码包装在Observable中。

RxJS-最新更新

在本教程中,我们将使用RxJS版本6。 RxJS通常用于处理响应式编程,并且在Angular,ReactJS等中经常使用。 Angular 6开始默认情况下会加载rxjs6。

与版本6相比,RxJS版本5的处理方式有所不同。如果将RxJS 5更新为6,则代码将会被破坏。在下边,我们将看到处理版本更新的解决方法。

如果您要将RxJS更新为6,并且不想更改代码,也可以这样做,需要安装以下软件包

npm install --save-dev rxjs-compact

该软件包将负责提供向后兼容性,并且旧代码将在RxJS版本6上正常运行。如果要对代码进行更改以使其在RxJS 6上正常运行,则需要进行以下修改。

用于运算符,可观察对象,主题的程序包已进行了重组,因此,对导入进行了重大修改,下面将对其进行说明。

导入运算符

根据版本5,使用运算符,需要导入以下语句:

import 'rxjs/add/operator/mapTo'
import 'rxjs/add/operator/take'
import 'rxjs/add/operator/tap'
import 'rxjs/add/operator/map'

在RxJS版本6中,导入将如下所示:

import {mapTo, take, tap, map} from "rxjs/operators"

导入创建可观察对象的方法

根据版本5,在使用Observables时,需要导入以下语句:

import "rxjs/add/observable/from";
import "rxjs/add/observable/of";
import "rxjs/add/observable/fromEvent";
import "rxjs/add/observable/interval";

在RxJS版本6中,导入将如下所示:

import {from, of, fromEvent, interval} from 'rxjs';

导入可观察对象

在RxJS版本5中,在使用Observables时,应包含以下import语句:

import { Observable } from 'rxjs/Observable'

在RxJS版本6中,导入将如下所示:

import { Observable } from 'rxjs'

导入主题

在RxJS版本5中,这样导入:

import { Subject} from 'rxjs/Subject'

在RxJS版本6中,导入将如下所示:

import { Subject } from 'rxjs'

如何在RxJS 6中使用运算符?

pipe()方法可用于创建可观察对象。它是从5.5版添加到RxJS的。现在,使用pipe()可以按顺序一起处理多个运算符。这是在RxJS版本5中使用运算符的方式:

import "rxjs/add/observable/from";
import 'rxjs/add/operator/max'

let list1 = [1, 6, 15, 10, 58, 2, 40];

from(list1).max((a,b)=>a-b).subscribe(x => console.log("The Max value is "+x));

从RxJS 5.5版开始,我们必须使用pipe()执行运算符:

import { from } from 'rxjs';
import { max } from 'rxjs/operators';

from(list1).pipe(max((a,b)=>a-b)).subscribe(x => console.log(
"The Max value is "+x)
);

运算符重命名

在开发RxJS期间,一些运算符由于与javascript关键字冲突或匹配而被重命名。列表如下所示-

xxx

RxJS-可观察对象

Observable是创建观察者并将其附加到源目标的函数,例如,单击,来自dom元素的鼠标事件或Http请求等期望获取值的源目标。

Observer是具有回调函数的对象,当与Observable发生交互时即会被调用,比如按钮单击,Http请求等都会触发。

我们将讨论以下内容

  • 创建可观察对象
  • 订阅可观察对象
  • 执行可观察对象

创建可观察对象

可以使用Observable构造函数和Observable create方法并通过将subscription函数作为参数传递给Observable来创建Observable,如下所示:

testrx.js

import { Observable } from 'rxjs';

var observable = new Observable(
function subscribe(subscriber) {
subscriber.next("我的第一个可观察对象")
}
);

我们创建了一个可观察对象,并使用可观察对象内部可用的subscription.next方法添加了一条消息"我的第一个可观察对象"。

我们还可以使用Observable.create()方法创建Observable,如下所示:

testrx.js

import { Observable } from 'rxjs';

var observer = Observable.create(
function subscribe(subscriber) {
subscriber.next("My First Observable")
}
);

订阅可观察对象

您可以按照以下方式订阅可观察对象:

testrx.js

import { Observable } from 'rxjs';

var observer = new Observable(
function subscribe(subscriber) {
subscriber.next("My First Observable")
}
);

observer.subscribe(x => console.log(x));

订阅观察者后,它将开始执行Observable。

在浏览器控制台中看到:

xxx

执行可观察对象

观察者在订阅时被执行。观察者是具有三种方法的对象,这些方法会被通知执行,

next() -此方法将发送数字,字符串,对象等值。

complete() -此方法将不发送任何值,并指示已完成。

error() -此方法将发送错误(如果有)。

让我们创建可观察对象,实现上边三个通知方法并执行相同的操作。

testrx.js

import { Observable } from 'rxjs';

var observer = new Observable(
function subscribe(subscriber) {
try {
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
} catch(e){
subscriber.error(e);
}
}
);

observer.subscribe(
x => console.log(x),
(e) => console.log(e),
() => console.log("Observable is complete")
);

在上面的代码中,我们添加了complete和error方法。

try{
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
} catch(e){
subscriber.error(e);
}

要执行next,complete和error,我们必须调用subscribe方法,如下所示:

observer.subscribe(
x => console.log(x),
(e) => console.log(e),
() => console.log("Observable is complete")
);

仅当出现错误时,才会调用error方法。

这是在浏览器中看到的输出:

xxx

RxJS-运算符

运算符是RxJS的重要组成部分。运算符是一个纯函数,它以可观察对象作为输入,而输出也是可观察对象

使用运算符

要和运算符一起使用,我们需要一个pipe()方法。

使用pipe()的示例

let obs = of(1, 2, 3); // 一个 observable

obs.pipe(
operator1(),
operator2(),
operator3(),
operator3(),
)

在上面的示例中,我们使用 of 方法创建了一个可观察对象,接收参数值为1, 2, 3。现在,在该可观察对象上,您可以使用pipe()方法来执行任意数量的运算符,如上所示。运算符的执行将按可观察对象中的值顺序进行。

以下是一个工作示例:

import { of } from 'rxjs';
import { map, reduce, filter } from 'rxjs/operators';

let test1 = of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

let case1 = test1.pipe(
filter(x => x % 2 === 0),
reduce((acc, one) => acc + one, 0)
)

case1.subscribe(x => console.log(x)); // 30

在上面的示例中,我们使用了filter运算符,该函数对偶数进行过滤,接下来,我们使用了reduce()运算符,该运算符将对偶数求和,并在订阅时给出结果。

下边是我们将要讨论的Observable列表。

  • 创建
  • 数学相关的
  • 联结
  • 转换
  • 过滤
  • 实用工具
  • 有条件的
  • 多播
  • 错误处理

创建运算符

1. ajax

该运算符将针对给定的URL发出ajax请求。

2. from

此运算符将根据数组,类似数组的对象,promise,可迭代对象或类似可观察对象的对象创建可观察对象。

3. fromEvent

此运算符用于包装可以发出事件的元素(例如按钮,单击等),输出可观察对象。

4. fromEventPattern

该运算符将从用于注册事件处理程序的输入函数创建一个可观察对象。

5. interval

该运算符将在给定的时间内每次创建一个Observable。

6. of

该运算符将接受传递的参数,并将其转换为可观察对象。

7. range

该运算符将创建一个Observable,将根据提供的范围为您提​​供一个数字序列。

8. throwError

该运算符将创建一个可观察的对象,该对象将通知错误。

9. timer

该运算符将创建一个可观察对象,该对象将在超时后发出该值,并且该值将在每次调用后保持递增。

10. iif

该运算符将决定要订阅哪个Observable。

数学运算符

1. Count

count()运算符接收一个带值的Observable,并计算这个Observable发出的通知数量

2. Max

Max方法接收所有可观察对象的值,并返回具有最大值的可观察值

3. Min

Min方法将接收所有可观察对象的值,并返回具有最小值的可观察值。

4. Reduce

在reduce运算符中,累加器函数用于可观察的输入,并且累加器函数将以可观察的形式返回累加值,并将可选的种子值传递给累加器函数。

reduce()函数将接受两个参数,一个是累加器函数,第二个是种子值。

联结运算符

1. concat

创建一个输出Observable,该输出从给定的Observable顺序发出所有值,然后移至下一个。

2. forkJoin

接受一个ObservableInput数组或一个ObservableInput字典对象,并返回一个Observable,它发出与传递的数组完全相同顺序的值数组,或与传递的字典具有相同形状的值字典。

3. merge

创建一个输出Observable,该输出同时从每个给定输入Observable发出所有值。

4. race

它将返回一个可观察对象,该对象将是第一个发出值的可观察对象的镜像副本。

转换操作符

1. buffer

缓冲区对可观察对象进行操作,并将参数作为可观察对象。它将开始对数组中原始可观察对象发出的值进行缓冲,并在将可观察对象用作参数时发出相同的值。一旦观察到的实参作为参数发出,缓冲区将被重置并重新开始对原始缓冲区进行缓冲,直到输入的可观察物发出并重复相同的场景。

2. bufferCount

缓冲源Observable值,直到大小达到给定的最大bufferSize。

3. bufferTime

在特定时间段内缓冲源Observable值。

4. bufferToggle

缓冲源Observable值,该值从开口的发射开始,到closeingSelector的输出发射时结束。

5. bufferWhen

该运算符将以数组形式给出值,它将一个参数作为函数来决定何时关闭,发出和重置缓冲区。

6. expand

expand运算符接受一个函数作为参数,该函数以递归方式应用于源可观察的对象,也应用于输出可观察的对象。最终值是可观察的。

7. groupBy

在groupBy运算符中,根据特定条件对输出进行分组,并且将这些分组项作为GroupedObservable发出。

8. map

对于map运算符,将项目函数应用于源Observable的每个值,并将相同的输出作为Observable发出。

9. mapTo

每当源Observable发出一个值时,就将常量值与Observable一起输出。

10. mergeMap

对于mergeMap运算符,将对每个源值应用一个项目函数,并将其输出与输出的Observable合并。

11. switchMap

对于switchMap运算符,将对每个源值应用一个项目函数,并将其输出与输出Observable合并,并且给定的值是最近投影的Observable。

12. window

它接受一个可观察的参数windowboundaries,并在给定windowboundaries发出时返回一个嵌套的observable。

过滤运算符

1. debounce

仅在另一个Observable确定的特定时间段过去之后,才从Source Observable发出一个值,而没有其他源发出。

2. debounceTime

仅在经过特定时间间隔后才发出源Observable的值,而不会发出其他源信号。

3. distinct

返回一个Observable,它发出源Observable发出的所有项目,这些项目与以前的项目相比是不同的。

4. elementAt

在来自源Observable的发射序列中,在指定的索引处发射单个值。

5. filter

该运算符将根据给定的判断函数从源Observable过滤值。

6. first

该运算符将给出源Observable发出的第一个值。

7. last

该运算符将给出源Observable发出的最后一个值。

8. ignoreElements

该运算符将忽略源Observable中的所有值,仅执行对完成或错误回调函数的调用。

9. sample

每当另一个Observable(通知者)发出时,从Observable源中发出最近发出的值

10. skip

返回一个Observable,它跳过源Observable发出的第一个计数项。

11. throttle

从源Observable发出一个值,然后在另一个Observable确定的持续时间内忽略后续源值,然后重复此过程。

实用工具操作符

1. tap

此运算符将具有与可观察到的源相同的输出,并且可用于将值从可观察到的日志记录到用户。主值,错误(如果有)或任务已完成。

2. delay

该运算符根据给定的超时时间,延迟从源Observable发出值。

3. delayWhen

该运算符基于另一个观测值作为输入的超时时间,延迟从源Observable发出的值。

4. observeOn

基于输入调度程序的该运算符将重新发送来自源Observable的通知。

5. subscribeOn

此运算符有助于根据作为输入的调度程序异步预订源Observable。

6. timeInterval

该运算符将返回一个对象,该对象包含当前值以及使用当前调度程序计算出的当前值与先前值之间的时间间隔。

7. timestamp

返回时间戳以及从源Observable发出的值,该值说明发出该值的时间。

8. timeout

如果源Observable在给定的超时后未发出值,则此运算符将引发错误。

9. toArray

累积来自Observable的所有源值,并在源完成时将它们输出为数组。

条件运算符

1. defaultIfEmpty

如果源可观察项为空,则此运算符将返回默认值。

2. every

它将基于输入函数返回一个Observable,该输入函数满足源Observable上每个值的条件。

3. find

当源Observable的第一个值满足输入的判断函数条件时,将返回Observable。

4. findIndex

基于输入调度程序的该运算符将重新发送来自源Observable的通知。

5. isEmpty

如果输入Observable执行完完整的回调而不发出任何值,则此运算符将输出为true;如果输入observable发出任何值,则该运算符将为false。

多播操作符

1. multicast

多播操作符与其他订阅者共享创建的单个订阅。多播接受的参数是返回具有connect()方法的ConnectableObservable的主题或工厂方法。要订阅,必须调用connect()方法。

2. publish

该运算符返回ConnectableObservable,并且需要使用connect()方法订阅可观察对象。

3. publishBehavior

publishBehaviour使用BehaviourSubject,并返回ConnectableObservable。 connect()方法必须用于订阅创建的可观察对象。

4. publishLast

publishBehaviour使用AsyncSubject,并返回ConnectableObservable。 connect()方法必须用于订阅创建的可观察对象。

5. publishReplay

publishReplay利用行为主题,其中它可以缓冲值并将其重放给新订阅者,并返回ConnectableObservable。 connect()方法必须用于订阅创建的可观察对象。

6. share

它是mutlicast()运算符的别名,唯一的区别是您不必手动调用connect()方法来启动订阅。

错误处理运算符

1. catchError

该运算符负责在源Observable上捕获错误,返回新的Observable或错误。

2. retry

如果有错误,此运算符将尝试在源Observable上重试,并且将根据给定的计数参数进行重试。

RxJS-使用订阅

创建可观察对象后,要执行可观察对象,我们需要订阅它。

count()运算符

这里是一个简单的示例,说明如何订阅可观察对象。

例子1

import { of } from 'rxjs';
import { count } from 'rxjs/operators';

let all_nums = of(1, 7, 5, 10, 10, 20);
let final_val = all_nums.pipe(count());

final_val.subscribe(x => console.log("The count is "+x)); // The count is 6

订阅有一种称为unsubscribe()的方法。调用unsubscribe()方法将删除该可观察对象使用的所有资源,即该可观察对象将被取消。这是一个使用unsubscribe()方法的工作示例。

例子2

import { of } from 'rxjs';
import { count } from 'rxjs/operators';

let all_nums = of(1, 7, 5, 10, 10, 20);
let final_val = all_nums.pipe(count());

let test = final_val.subscribe(x => console.log("The count is "+x)); // The count is 6

test.unsubscribe(); // 取消订阅

订阅存储在变量test中。我们已经使用了test.unsubscribe()。

RxJS-使用Subjects

Subjects是可以多播(即与许多观察者交谈)的可观察对象。比如带有事件监听器的按钮,每次用户单击按钮时,都会执行监听事件的回调方法的功能,这和主题的功能是类似的。主题相当于一个事件中心。

下边将讨论以下内容:

  • 创建一个主题
  • 可观察对象和主题之间有什么区别?
  • Behaviour Subject
  • Replay Subject
  • AsyncSubject

创建一个主题

要处理主题,我们需要导入主题,如下所示:

import { Subject } from 'rxjs';

您可以如下创建主题对象:

const subject_test = new Subject();

该对象是具有三种方法的观察者(obsever)

  • next(v)
  • error(e)
  • complete()

订阅主题

您可以在主题上创建多个订阅,如下所示:

subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});

subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});

就像我们前面讨论的addlistener一样,订阅已注册到主题对象。

将数据传递给主题

您可以使用next()方法将数据传递给创建的主题。

subject_test.next("A");

数据将传递到在主题上添加的所有订阅。如果主题对象是一个全局单例对象,那么就相当于event bus事件中心了。

这是该主题的一个工作示例:

import { Subject } from 'rxjs';

const subject_test = new Subject();

/* a.js */
subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});

/* b.js */
subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});

subject_test.next("A");
subject_test.next("B");

通过调用新的Subject()创建subject_test对象。 subject_test对象引用了next(),error()和complete()方法。上面示例的输出如下所示-

输出

xxx

我们可以使用complete()方法来停止主题执行,如下所示。

示例

import { Subject } from 'rxjs';

const subject_test = new Subject();

subject_test.subscribe({
next: (v) => console.log(`From Subject : ${v}`)
});

subject_test.subscribe({
next: (v) => console.log(`From Subject: ${v}`)
});

subject_test.next("A");
subject_test.complete();
subject_test.next("B");

一旦调用complete,就不会再调用稍后的下一个方法。

输出

xxx

现在让我们看看如何调用error()方法。

以下是一个工作示例

import { Subject } from 'rxjs';

const subject_test = new Subject();

subject_test.subscribe({
error: (e) => console.log(`From Subject : ${e}`)
});

subject_test.subscribe({
error: (e) => console.log(`From Subject : ${e}`)
});

subject_test.error(new Error("There is an error"));

输出

xxx

可观察对象和主题之间有什么区别?

可观察者对象将与订阅者一对一通信。只要您订阅可观察对象,执行将从头开始。使用ajax发起Http请求,并由2个订阅者调用可观察对象。您将在浏览器网络选项卡中看到2个Http请求。

这是工作示例:

import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';

let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));

let subscriber1 = final_val.subscribe(a => console.log(a));

let subscriber2 = final_val.subscribe(a => console.log(a));

输出

xxx

xxx

现在,这里的问题是,我们希望共享相同的数据,但是不希望以2个Http调用为代价。我们要进行一次Http调用,并在订阅者之间共享数据。

使用主题可以做到这一点。它是可观察对象,也可以多播,即能与许多观察者通信。它可以在订阅者之间共享值。

这是使用主题的工作示例:

import { Subject } from 'rxjs';
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';

const subject_test = new Subject();

subject_test.subscribe({
next: (v) => console.log(v)
});

subject_test.subscribe({
next: (v) => console.log(v)
});

let final_val = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));
let subscriber = final_val.subscribe(subject_test);

输出

xxx

现在,您只能看到一个Http调用,并且被调用的订户之间共享相同的数据。

xxx

Behaviour Subject

行为主题将在调用时为您提供最新值,包括初始值

您可以如下所示创建行为主题:

import { BehaviorSubject } from 'rxjs';

const subject = new BehaviorSubject("Testing Behaviour Subject");
// 初始化behaviour subject,使用值"Testing Behaviour Subject"

这是使用行为主题的工作示例:

import { BehaviorSubject } from 'rxjs';

const behavior_subject = new BehaviorSubject("Testing Behaviour Subject"); // 初始值

behavior_subject.subscribe({
next: (v) => console.log(`observerA: ${v}`)
});

behavior_subject.next("Hello");

behavior_subject.subscribe({
next: (v) => console.log(`observerB: ${v}`)
});

behavior_subject.next("Last call to Behaviour Subject");

输出

xxx

Replay 重播主题

重播主题类似于行为主题,但是,它可以缓冲值并将其重播给新的订阅者。

这是重播主题的工作示例:

import { ReplaySubject } from 'rxjs';

const replay_subject = new ReplaySubject(2);
// 缓存最近的2个值,遇到新的新的订阅,会提供这些过时的值

replay_subject.subscribe({
next: (v) => console.log(`Testing Replay Subject A: ${v}`)
});

replay_subject.next(1);
replay_subject.next(2);
replay_subject.next(3);

replay_subject.subscribe({
next: (v) => console.log(`Testing Replay Subject B: ${v}`)
});

replay_subject.next(5);

重播主题上使用的缓冲区值为2。因此,最后两个值将被缓冲并用于新的订阅者。

输出

xxx

异步主题

在AsyncSubject的情况下,最后一个调用的值将传递给订阅者,并且只有在调用complete()方法之后才能完成。

这是相同的工作示例:

import { AsyncSubject } from 'rxjs';

const async_subject = new AsyncSubject();

async_subject.subscribe({
next: (v) => console.log(`Testing Async Subject A: ${v}`)
});

async_subject.next(1);
async_subject.next(2);
async_subject.complete();

async_subject.subscribe({
next: (v) => console.log(`Testing Async Subject B: ${v}`)
});

在这里,在调用complete之前,传递给主题的最后一个值是2,与提供给新订阅者的值相同。

输出

xxx

RxJS-使用调度程序

调度程序控制何时启动和通知订阅的执行

要使用调度程序Scheduler,我们需要以下内容:

import { Observable, asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';

这是一个工作示例,其中,我们将使用调度程序来决定执行情况:

import { Observable, asyncScheduler } from 'rxjs';
import { observeOn } from 'rxjs/operators';

var observable = new Observable(function subscribe(subscriber) {
subscriber.next("My First Observable");
subscriber.next("Testing Observable");
subscriber.complete();
}).pipe(
observeOn(asyncScheduler)
);

console.log("Observable Created");

observable.subscribe(
x => console.log(x),
(e)=>console.log(e),
()=>console.log("Observable is complete")
);

console.log('Observable Subscribed');

输出

xxx

没有调度程序,输出将如下所示:

xxx

使用RxJS和Angular

在本章中,我们将看到如何在Angular中使用RxJS。我们不会在这里介绍Angular的安装过程,要了解有关Angular安装的信息,请参考官方文档

我们将直接处理一个示例,该示例将使用RxJS中的Ajax加载数据。

app.component.ts

import { Component } from '@angular/core';
import { environment } from './../environments/environment';
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators'

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = '';
data;

constructor() {
this.data = "";
this.title = "Using RxJs with Angular";
let a = this.getData();
}

getData() {
const response = ajax('https://jsonplaceholder.typicode.com/users')
.pipe(
map(e => e.response)
);

response.subscribe(res => {
console.log(res);
this.data = res;
});
}
}

app.component.html

<div>
<h3>{{title}}</h3>
<ul *ngFor="let i of data">
<li>{{i.id}}: {{i.name}}</li>
</ul>
</div>

<router-outlet></router-outlet>

我们使用了RxJS的ajax,它将从该URL加载数据-https://jsonplaceholder.typicode.com/users。

编译时,显示如下所示:

xxx

使用RxJS和ReactJS

在本章中,我们将看到如何将RxJ与ReactJS一起使用。我们不会在这里介绍Reactjs的安装过程,要了解ReactJS的安装,请参考官方文档

我们将直接在下面的示例中工作,在该示例中,将使用RxJS中的Ajax加载数据。

index.js

import React, { Component } from "react";
import ReactDOM from "react-dom";
import { ajax } from 'rxjs/ajax';
import { map } from 'rxjs/operators';

class App extends Component {
constructor() {
super();
this.state = { data: [] };
}

componentDidMount() {
const response = ajax('https://jsonplaceholder.typicode.com/users').pipe(map(e => e.response));

response.subscribe(res => {
this.setState({ data: res });
});
}

render() {
return (
<div>
<h3>Using RxJS with ReactJS</h3>
<ul>
{this.state.data.map(el => (
<li>
{el.id}: {el.name}
</li>
))}
</ul>
</div>
);
}
}

ReactDOM.render(<App />, document.getElementById("root"));

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>ReactJS Demo</title>
<head>
<body>
<div id="root"></div>
</body>
</html>

我们使用了RxJS的ajax,它将从网址(https://jsonplaceholder.typicode.com/users)加载数据。

编译时,显示如下:

xxx