变换操作符
1. scan¶
将上次的结果作为这下一次的初始值, 运算完进行发射。
1 2 3 4 5 6 7 8 | const source$ = interval(1000).pipe( filter(val => val % 2 === 0), scan((oldVal, newVal) => oldVal + newVal), take(4) ); // 输出: '0', '2', '6', '12' source$.subscribe(val => console.log(val)); |
数据流分析:
1 2 3 4 5 6 | // scan的初始值为0, 每一次累加完的结果, 立马发射出去, 作为下一次的初始值进行累加 interval$: 0------1------2------3------4------5------6------ filter$: 0-------------2-------------4-------------6------ \ \ \ 0+2 2+4 6+6 scan$: 0-------------2------------ 6-------------12----- |
数据流图例:

2. reduce¶
reduce和scan比较相似, 唯一的不同点在于, reduce只是发射最终值。
1 2 3 4 5 6 7 8 | const source$ = interval(1000).pipe( filter(val => val % 2 === 0), take(4), reduce((oldVal, newVal) => oldVal + newVal) ); // 输出: '12' source$.subscribe(val => console.log(val)); |
数据流图例:

3. map¶
将源数据流中的元素,经过处理,映射成另一个元素。
1 2 3 4 5 6 7 8 | // html // 可以尝试用 div>input#length生成 <div><input type="text" id="length"></div> // ts const length = document.getElementById('length') // 将输入的值*10 const source$ = fromEvent(length, 'keyup').pipe(map(ev => (ev.target as HTMLInputElement).value * 10)); |
数据流图例:

4. mapTo/pluck¶
pluck、mapTo是map的一种变形,可以通过map得到它们相对应的结果。
- mapTo的作用在于,可以设置一个常量。比如button的click事件,我们不需要关心其值到底什么,我们只关心事件是否发生。
1 2 3 4 5 6 7 8 | // html // 可以尝试用 div>input#length生成 <div><input type="text" id="length"></div> // ts const length = document.getElementById('length') // 无论输入什么值,都设置成"1" const source$ = fromEvent(length, 'keyup').pipe(mapTo(1)); |
- pluck获取控件的属性值,层级可以是二级、三级甚至更多。
1 2 3 4 5 6 7 8 | // html // 可以尝试用 div>input#length生成 <div><input type="text" id="length"></div> // ts const length = document.getElementById('length') // 获取输入的值 const source$ = fromEvent(length, 'keyup').pipe(pluck('target', 'value')); |