RxJS简介
Reactive Extensions for JavaScript
RxJS 是一个库,它通过使用 observable 序列来编写异步和基于事件的程序。它提供了一个核心类型 Observable,附属类型 (Observer、 Schedulers、 Subjects) 和受 [Array#extras] 启发的操作符 (map、filter、reduce、every, 等等),这些数组操作符可以把异步事件作为集合来处理。
RxJS核心概念
Observable (可观察对象):表示一个概念,这个概念是一个可调用的未来值或事件的集合。
Observer (观察者):一个回调函数的集合,它知道如何去监听由 Observable 提供的值。
Subscription (订阅):表示 Observable 的执行,主要用于取消 Observable 的执行。
Operators (操作符): 采用函数式编程风格的纯函数 (pure function),使用像 map、filter、concat、flatMap 等这样的操作符来处理集合。
Subject (主体): 相当于 EventEmitter,并且是将值或事件多路推送给多个 Observer 的唯一方式。
Schedulers(调度器):用来控制并发并且是中央集权的调度员,允许我们在发生计算时进行协调,例如 setTimeout 或 requestAnimationFrame 或其他。
Defer
原理图:
defer允许仅在观察者订阅时创建观察者,并为每个观察者创建一个新的观察者。它等待,直到观察者订阅它,然后它生成一个观察者,通常带有观察者工厂功能。它为每个订阅用户重新进行此操作,因此尽管每个订阅用户可能认为自己正在订阅相同的 Observable,但实际上每个订阅用户都拥有自己的个人 Observable。
示例:
import { defer, fromEvent } from 'rxjs';
const clicksOrInterval = defer(function () {
return Math.random() > 0.5
? fromEvent(document, 'click')
: interval(1000);
});
clicksOrInterval.subscribe(x => console.log(x));
导致以下行为:
如果 Math.random() 的结果大于 0.5 它会监听点击“文档”上的任意位置;
单击文档时, 如果结果小于0.5将 MouseEvent 对象记录到控制台, 大于 0.5 时会发出递增的数字,每秒(1000 毫秒)一个。
FromEvent
原理图:
fromEvent接受事件目标作为第一个参数,该目标是具有注册事件处理函数的方法的对象。作为第二个参数,它使用指示我们要侦听的事件类型的字符串。fromEvent支持所选类型的事件目标,下面将对其进行详细描述。如果您的事件目标与列出的目标不匹配,则应使用 fromEventPattern,可以在任意 API 上使用。对于所支持的 API fromEvent,它们用于添加和删除事件处理程序函数的方法具有不同的名称,但是它们都接受描述事件类型和函数本身的字符串,只要发生所述事件,就会调用该字符串。
每次预订结果 Observable 时,事件处理函数将在给定事件类型上注册到事件目标。当该事件触发时,作为第一个参数传递给已注册函数的值将由输出 Observable 发出。取消订阅 Observable 时,将从事件目标中取消注册功能
示例:
发出 DOM 文档上发生的点击
import { fromEvent } from 'rxjs';
const clicks = fromEvent(document, 'click');
clicks.subscribe(x => console.log(x));
//result:
// PointerEvent {isTrusted: true, pointerId: 1, width: 1, height: 1, pressure: 0, …}
使用带有捕获选项的 addEventListener
import { fromEvent } from 'rxjs';
const clicksInDocument = fromEvent(document, 'click', true);
const clicksInDiv = fromEvent(someDivInDocument, 'click');
clicksInDocument.subscribe(() => console.log('document'));
clicksInDiv.subscribe(() => console.log('div'));
默认情况下,事件会在 DOM 树中冒泡,因此通常当我们单击文档中的 div 时,“div”会首先记录,然后是“document”。 由于我们指定了可选的 `capture` 选项,document 会在 DOWN DOM 树时捕获事件,因此控制台会先记录“document”,然后再记录“div”。
Interval
原理图:
interval返回一个 Observable,它发出无限个升序整数序列,并在这些发射之间选择一个固定的时间间隔。第一次发射不会立即发送,而只会在第一个周期过去之后发送。默认情况下,该运算符使用 async SchedulerLike 来提供时间的概念,但是您可以将任何时间传递 SchedulerLike 给它。
示例:
import { interval } from 'rxjs';
import { take } from 'rxjs/operators';
const numbers = interval(1000);
const takeFourNumbers = numbers.pipe(take(4));
takeFourNumbers.subscribe(x => console.log('Next: ', x));
// results:
// Next: 0
// Next: 1
// Next: 2
// Next: 3
Timer
原理图:
timer 返回一个 Observable,它发出一个无限的升序序列 具有固定时间间隔的整数 period您选择的 在这些排放之间。 第一次发射发生在指定的时间之后 dueTime。 初始延迟可能是 Date。 默认情况下, 运算符使用 async SchedulerLike来提供时间概念,但是您 可以将任何 传递 SchedulerLike东西 给它。 如果 period未指定,则输出 “可观察”仅发出一个值 0。 否则,它会发出无限顺序。
示例:
发出升序的数字,每秒3秒后开始(1000ms)
import { timer } from 'rxjs';
const numbers = timer(3000, 1000);
numbers.subscribe(x => console.log(x));
//results:
//0
//1
//2
//3
//4
//…