八.take,first,takeUntil,concatAll
讲四个 operators,并实现拖拉功能
take
take(x)
取结果的前 X 个元素
var source = Rx.Observable.interval(1000);
var example = source.take(3);
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// complete
最后会调用一个 complete, 有点意外.
source : -----0-----1-----2-----3--..
take(3)
example: -----0-----1-----2|
first
first()
等于 take(1)
takeUntil
Observable1.takeUntil(Observable2)
observable2 发送值时, observable1 会被调用complete.
var source = Rx.Observable.interval(1000);
var click = Rx.Observable.fromEvent(document.body, 'click');
var example = source.takeUntil(click);
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// 3
// complete (點擊body了
source : -----0-----1-----2------3--
click : ----------------------c----
takeUntil(click)
example: -----0-----1-----2----|
concatAll
Observable1.concatAll()
将 将高阶 Observable,转换 为 一阶 Observable.
依次等待并同步输出每一个 Observable 值的输出值.
mergeAll()
并行所有Observable, 并同步输出任意 Observable 值的输出值.
带ALL的都是高阶Observable 操作符
var click = Rx.Observable.fromEvent(document.body, 'click');
var source = click.map(e => Rx.Observable.of(1,2,3));
var example = source.concatAll();
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
click : ------c------------c--------
map(e => Rx.Observable.of(1,2,3))
source : ------o------------o--------
\ \
(123)| (123)|
concatAll()
example: ------(123)--------(123)------------
var obs1 = Rx.Observable.interval(1000).take(5);
var obs2 = Rx.Observable.interval(500).take(2);
var obs3 = Rx.Observable.interval(2000).take(1);
var source = Rx.Observable.of(obs1, obs2, obs3);
var example = source.concatAll();
example.subscribe({
next: (value) => { console.log(value); },
error: (err) => { console.log('Error: ' + err); },
complete: () => { console.log('complete'); }
});
// 0
// 1
// 2
// 3
// 4
// 0
// 1
// 0
// complete
source : (o1 o2 o3)|
\ \ \
--0--1--2--3--4| -0-1| ----0|
concatAll()
example: --0--1--2--3--4-0-1----0|
用上述四个函数完成简易拖拉
需求:
- 画面上有个 dom元素 (#drag)
- 鼠标在 #drag 上 按下左键(mousedown), 开始 监听鼠标移动(mousemove) 的位置
- 鼠标 左键放开(mouseup), 结束监听鼠标移动
- 鼠标移动被监听时, 同时需要 修改原件位置属性 造成拖拽效果.
const dragDOM = document.getElementById('drag');
const body = document.body;
const mouseDown = Rx.Observable.fromEvent(dragDOM, 'mousedown');
const mouseUp = Rx.Observable.fromEvent(body, 'mouseup');
const mouseMove = Rx.Observable.fromEvent(body, 'mousemove');
mouseDown
.map(event => mouseMove.takeUntil(mouseUp))
.concatAll()
.map(event => ({ x: event.clientX, y: event.clientY }))
.subscribe(pos => {
dragDOM.style.left = pos.x + 'px';
dragDOM.style.top = pos.y + 'px';
})
总结
take, first, takeUntil, concatAll 用法 和 简易拖拽