8.take,first,takeUntil,concatAll


八.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|

用上述四个函数完成简易拖拉

需求:

  1. 画面上有个 dom元素 (#drag)
  2. 鼠标在 #drag 上 按下左键(mousedown), 开始 监听鼠标移动(mousemove) 的位置
  3. 鼠标 左键放开(mouseup), 结束监听鼠标移动
  4. 鼠标移动被监听时, 同时需要 修改原件位置属性 造成拖拽效果.
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 用法 和 简易拖拽


文章作者: 罗紫宇
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 罗紫宇 !
  目录