- RxJS官方教程(一) 概览
- RxJS官方教程(二) Observable
- RxJS官方教程(三) Observable剖析
- RxJS官方教程(四) Observer和Subscription
- RxJS官方教程(五) Subject
- RxJS官方教程(六) 算子
Operator 算子
虽然Observable是RxJS的基础,但是它的好用主要在于其算子。算子允许以声明方式轻松组合复杂异步代码。
什么是算子?
算子是Observable的一种方法,如.map(...)
,.filter(...)
,.merge(...)
,当调用时,它们不会改变现有的Observable。相反,它们返回一个新的 Observable,其订阅逻辑基于第一个Observable。
算子是一个基于当前Observable创建新Observable的函数。这是一个纯粹的操作:前一个Observable保持不变。
算子本质上是一个纯函数,它将一个Observable作为输入,并生成另一个Observable作为输出。订阅输出的Observable也将订阅输入的Observable。在下面的示例中,我们创建一个自定义算子,将从输入Observable接收的每个值乘以10:
function multiplyByTen(input) {
var output = Rx.Observable.create(function subscribe(observer) {
input.subscribe({
next: (v) => observer.next(10 * v),
error: (err) => observer.error(err),
complete: () => observer.complete()
});
});
return output;
}
var input = Rx.Observable.from([1,2,3,4]);
var output = multiplyByTen(input);
output.subscribe(x => console.log(x));
输出:
10
20
30
40
请注意,订阅output
将导致input
订阅Observable。我们称之为“算子订阅链”。
实例算子与静态算子
什么是实例算子?通常在引用算子时,当它们是Observable实例上的方法,我们称它是实例算子。例如,如果运算符multiplyByTen
是官方实例算子,它看起来大致如下:
Rx.Observable.prototype.multiplyByTen = function multiplyByTen() {
var input = this;
return Rx.Observable.create(function subscribe(observer) {
input.subscribe({
next: (v) => observer.next(10 * v),
error: (err) => observer.error(err),
complete: () => observer.complete()
});
});
}
实例算子是使用
this
关键字来推断什么是输入Observable的函数。
注意input
Observable不再是函数参数,它被假定为this
对象。这就是我们如何使用这样的实例算子:
var observable = Rx.Observable.from([1, 2, 3, 4]).multiplyByTen();
observable.subscribe(x => console.log(x));
什么是静态算子?除了实例算子,静态算子是直接附加到Observable类的函数。静态算子在内部不使用this
关键字,而是完全依赖于其参数。
静态算子是附加到Observable类的纯函数,通常用于从头创建Observable。
最常见的静态算子类型是所谓的Creation Operators。它们不是将输入Observable转换为输出Observable,而是简单地采用非Observable参数,如数字,并创建一个新的Observable。
静态创建算子的典型示例是interval
函数。它需要一个数字(不是Observable)作为输入参数,并产生一个Observable作为输出:
var observable = Rx.Observable.interval(1000 /* number of milliseconds */);
创建算子的另一个例子是我们在前面的例子中广泛使用的create
。请在此处查看所有静态创建算子的列表。
但是,静态算子可能与简单创建的性质不同。一些联合算子可以是静态的,例如merge
,combineLatest
,concat
等等,因为他们采取多种观测量作为输入,不只是一个,例如:
var observable1 = Rx.Observable.interval(1000);
var observable2 = Rx.Observable.interval(400);
var merged = Rx.Observable.merge(observable1, observable2);
弹珠图
为了解释算子的工作原理,文本描述通常是不够的。许多算子与时间有关,例如他们可能以不同的方式延迟,采样,节流或去抖值。图表通常是更好的工具。Marble Diagrams是算子工作方式的可视化表示,包括输入Observable(s),算子及其参数以及输出Observable。
在弹珠图中,时间流向右侧,图表描述了如何在Observable执行中发出值(“弹珠”)。
您可以在下面看到弹珠图的解剖结构。
在整个文档站点中,我们广泛使用弹珠图来解释算子的工作方式。它们在其他环境中也可能非常有用,例如在白板上甚至在我们的单元测试中(如ASCII图)。
选择一个算子
您是否需要为您的问题找到算子?首先从下面的列表中选择一个选项:
- 我有一个现有的Observable,...
- 我有一些Observables作为一个Observable组合在一起,并且......
- 我还没有Observables,而且......
算子的类别
存在用于不同目的的算子,它们可以被分类为:创建,转换,过滤,组合,多播,错误处理,工具等。在以下列表中,您将找到按类别组织的所有算子。
创建算子
ajax
bindCallback
bindNodeCallback
create
defer
empty
from
fromEvent
fromEventPattern
fromPromise
generate
interval
never
of
repeat
repeatWhen
range
throw
timer
转换算子
buffer
bufferCount
bufferTime
bufferToggle
bufferWhen
concatMap
concatMapTo
exhaustMap
expand
groupBy
map
mapTo
mergeMap
mergeMapTo
mergeScan
pairwise
partition
pluck
scan
switchMap
switchMapTo
window
windowCount
windowTime
windowToggle
windowWhen
过滤算子
debounce
debounceTime
distinct
distinctKey
distinctUntilChanged
distinctUntilKeyChanged
elementAt
filter
first
ignoreElements
audit
auditTime
last
sample
sampleTime
single
skip
skipLast
skipUntil
skipWhile
take
takeLast
takeUntil
takeWhile
throttle
throttleTime
组合算子
combineAll
combineLatest
concat
concatAll
exhaust
forkJoin
merge
mergeAll
race
startWith
switch
withLatestFrom
zip
zipAll
广播算子
错误处理算子
通用算子
do
delay
delayWhen
dematerialize
finally
let
materialize
observeOn
subscribeOn
timeInterval
timestamp
timeout
timeoutWith
toArray
toPromise