在RxJS中提供一些列transformation类的操作符,分两类

  • 映射数据-对每个数据做转化
  • 数据重新组合
适用操作符 功能需求
map 将每个元素用映射函数产生新的数据
mapTo 将数据流中每个元素映射为同一个数据
pluck 提取数据流中每个数据的某个字段
windowTime,windowCount,windowWhen,windowToggle,window 产生高阶Observable对象
bufferTime,bufferCount,bufferWhen,bufferToggle,buffer 产生数组构成的数据流
concatMap,mergeMap,switchMap,exhaustMap 映射产生高阶Observable对象然后合并
scan,mergeScan 产生规约运算结果组成的数据流

map

虽然与javascript的数组类型的map同名,但两者是有差异的:

  • 相同点-接受一个函数(project)作为参数,指定了数据映射的逻辑。
  • 不同点-接受一个可选参数thisArg,用于指定函数project执行时的this值。
    1
    2
    3
    4
    5
    6
    7
    8
    const source$ = of(3,1,4)
    const context = {separator: '::'};
    const mapFunc = (function(separator) {
    return function(value, index) {
    return `${value} ${separator} ${index}`;
    }
    })(context.separator)
    source$.map(mapFunc, context)
    3 :: 0, 1 :: 1, 4 :: 2×3

mapTo

本质就是简化版map

1
2
3
Observable.prototype.mapTo = function(value) {
return this.map(x => value);
}

pluck

含义为”拔”,把上游数据中特定字段的值”拔”出来。

1
2
3
4
5
6
7
const source$ = of(
{name: "RxJS", version: "v1"},
{name: "React", version: "v2"},
{name: "Angular", version: "v3"},
{name: "Vue", version: "v4"},
)
source$.pluck('name', 'defaultName')

×4RxJS, React, Angular, Vue

缓存窗口:无损回压控制

我们可以利用过滤类操作符进行回压控制,不过过滤类操作符的回压控制属于”有损”控制

  • 有损回压-舍弃一些数据
  • 无损回压-在一段时间内产生的数据放到一个数据集合里

回压的仓库-数据集合

  • 支持数组的以buffer开头
  • 支持Observable对象的以window开头

无损回压原理

当上游数据传来是,会把多个上游数据缓存到数组或Observable对象传给下游。

windowTime

缓存上游数据,参数只有一个,指定产生缓冲窗口的间隔

1
2
const source$ = timer(0, 100)
source$.windowTime(400)

012345678

bufferTime

1
2
const source$ = timer(0, 1000)
source$.pipe(bufferTime(4000))

0,1,2,34,5,6,7

windowToggle

利用Observable来控制缓冲窗口的开和关,两个参数

  1. opening$产生一个数据,代表一个缓冲窗口的开始
  2. closingSelector,用来获取缓冲窗口结束
    1
    2
    3
    4
    const source$ = timer(0, 1000)
    const opening$ = timer(0, 4000)
    const closingSelector = value => value % 2 === 0 ? timer(2000) : timer(1000)
    source$.pipe(opening$, closingSelector)
    01458

高阶map

普通map只是把一个数据映射为另一个数据
高阶map把一个数据映射为一个Observable对象

1
2
3
4
5
const source$ = interval(2000)
const project = (value, index) => {
interval(1000).take(5)
}
source$.pipe(map(project))

01234012301
返回给下游的Observable可以使用RxJS提供的高阶map操作符

  • concatMap
  • mergeMap
  • switchMap
  • exhaustMap

小结

转化类操作符,除了数据流的合并和过滤功能,也可以用来控制回压,这是一种无损的回压控制方法,本质上是把如何过滤掉无关信息的决策权交给了下游