美文网首页
RawRxJS笔记

RawRxJS笔记

作者: Sczlog | 来源:发表于2018-12-11 17:37 被阅读5次

    *不是我没学,我只是懒得不想把Raw笔记转码了而已。~~懒得要死~~

    注:本文学习环境为RxJs5.x版本,目前使用环境为RxJs6,故部分声明代码不同

    例如:大部分operator将不需要前置的Rx.Observable,直接调用即可。

    分割线-------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Observable可以同时处理同步与异步传来的信息

    var observable = Rx.Observable    // 1.创建一个observable对象,新版应改为直接使用Observable?

        .create(function(observer) {

            observer.next('Jerry'); // 同步部分

            observer.next('Anna'); 

            setTimeout(() => {      // 异步部分

                observer.next('RxJS 30 days!');

    observer.complete();  //停止observable,此后部分不会被显示。

    observer.next("not work");

            }, 30)

        })

    console.log('start');

    observable.subscribe(function(value) {  // 2.订阅这个observable对象,并为其设置观察者方法。

        console.log(value);

    });

    console.log('end');

    输出:

    start

    Jerry

    Anna

    end

    RxJS 30 days!

    对于subscribe方法来说,可以为其设定针对不同情况的不同处理,例如针对complete与异常抛出

    var observer = {

    next: function(value) {      //.next()走这里

    console.log(value);

    },

    error: function(error) {      // 出现异常走这里

    console.log('Error: ', error)

    },

    complete: function() {        //.complete()走这里

    console.log('complete')

    }

    }

    observable.subscribe(observer)    // 而后进行订阅

    以上可以简化为传三个function参数:

    observable.subscribe(

        v => { console.log(v); },

        e => { console.log('Error: ', e); },

        () => { console.log('complete') }

    )

    订阅函数subscribe()具有自己的返回值,是一个subscription对象

    该对象可以用来停止某些不会complete()的订阅过程,即unsubscribe();

    observable的常用creation operator

    这些操作符都是用来创建实例的操作符:

    of()传入多个参数,observer将会将其依次next()传出,完成时则传出complete()

    var source = Rx.Observable.of('Jerry', 'Anna');

    from()与of()很相似,只不过传入的是一个可以被枚举的参数,例如array,set,iterator甚至是promise(可以使用fromPromise)等等(object和string应该能被传入)

    var source = Rx.Observable.from(['Jerry', 'Anna']);

    fromEvent()用于监听事件,在next中传回的将是被触发的事件对象

    var source = Rx.Observable.fromEvent(document.body, 'click');

    fromEventPattern()传入一个事件的触发与取消,监听一次?

    var source = Rx.Observable

        .fromEventPattern(

            (handler) => egghead.addListener(handler),

            (handler) => egghead.removeListener(handler)

        );

    empty()传入一个空的观测序列,被订阅后立刻输出complete

    var source = Rx.Observable.empty();

    never()传入一个永远不会结束但什么也不干的观测序列,被订阅后什么都不会发生

    var source = Rx.Observable.never();

    throw()传入一个立刻回抛出异常的观测序列,被订阅后立刻抛出这个错误

    var source = Rx.Observable.throw('Oop!');

    interval()传入一个按interval传入参数(单位为ms)间隔发出next(从0开始)的观测序列,其中next()传出的值为次数,由0开始

    var source = Rx.Observable.interval(1000);

    timer()与之类似,当传入一个参数时类似于setTimeout,当设定两个参数时,第一个参数表示第一次next抛出的时间,第二个参数表示每次next的间隔

    var source = Rx.Observable.timer(1000, 5000);

    var source = Rx.Observable.timer(1000);

    分割线-------------------------------------------------------------------------------------------------------------------------------------------------------------------

    Operator:

    map()将原有observable按一定规则映射成为一个新的observable

    var source = Rx.Observable.interval(1000);

    var newest = source.map(x => x + 2);

    mapTo()将原有observable按映射成为一个传出定值的observable

    var source = Rx.Observable.interval(1000);

    var newest = source.mapTo(2);

    filter()将原有的observable根据规则过滤成为一个新的observable

    var source = Rx.Observable.interval(1000);

    var newest = source.filter(x => x % 2 === 0);

    take()取原有的observable的前n项,并传出complete()

    var source = Rx.Observable.interval(1000);

    var example = source.take(3);

    first()等同于take(1)

    takeLast()指去最后n个,顺序依然是正序

    var source = Rx.Observable.interval(1000).take(6);

    var example = source.takeLast(2);          // 输出4,5

    last()等同于takeLast(1)

    skip()跳过n个next

    var source = Rx.Observable.interval(1000);

    var example = source.skip(3);

    takeUntil()在某件事发生时,出发observable的complete()

    var source = Rx.Observable.interval(1000);

    var click = Rx.Observable.fromEvent(document.body, 'click');

    var example = source.takeUntil(click);

    concat()把多个Observable合并成一个

    var source = Rx.Observable.interval(1000).take(3);

    var source2 = Rx.Observable.of(3)

    var source3 = Rx.Observable.of(4,5,6)

    var example = source.concat(source2, source3);

    startWith()是在原observable发送之前添加一些不是observable但是需要被发送的元素

    var source = Rx.Observable.interval(1000);

    var example = source.startWith(0);

    concatAll()将一个内含Observable的Observable中的所有Observable合并成为一个Observable

    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();

    concat和concatAll会严格按顺序执行,如上文例子输出为0,1,2,3,4,0,1,0

    merge()与concat类似,但是最大的区别在于多个observable会并发进行,任意一个observable发送next时都会对之进行处理

    var source = Rx.Observable.interval(500).take(3);

    var source2 = Rx.Observable.interval(300).take(6);

    var example = source.merge(source2);

    一个简单的RxJs拖拽代码

    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';

      })

    分割线-------------------------------------------------------------------------------------------------------------------------------------------------------------------

    combineLatest()每当一个observable输出数据时则调用回调函数,若另一个observable并没有数据输出则不调用回调函数。

    var source = Rx.Observable.interval(500).take(3);

    var newest = Rx.Observable.interval(300).take(6);

    var example = source.combineLatest(newest, (x, y) => x + y);

    source : ----0----1----2|

    newest : --0--1--2--3--4--5|

    combineLatest(newest, (x, y) => x + y);

    example: ----01--23-4--(56)--7|

    输出拆分为 0+0, 1+0, 2+0,1+2,3+1,4+1,2+4,5+2;

    withLatestFrom()与combineLastest类似,但是只有主函数输出时才会执行回调函数

    var main = Rx.Observable.from('hello').zip(Rx.Observable.interval(500), (x, y) => x);

    var some = Rx.Observable.from([0,1,0,0,0,1]).zip(Rx.Observable.interval(300), (x, y) => x);

    var example = main.withLatestFrom(some, (x, y) => {

        return y === 1 ? x.toUpperCase() : x;

    });

    订阅后输出helLO

    zip()则是把每个observable相同发送次数的值放在一次进行操作

    var source = Rx.Observable.interval(500).take(3);

    var newest = Rx.Observable.interval(300).take(6).takeLast(4);

    var example = source.zip(newest, (x, y) => x + y);

    source : ----0----1----2|

    newest : --2--3--4--5|

        zip(newest, (x, y) => x + y)

    example: ----2----4----6|

    输出拆分为:0+2,1+3,2+4

    利用zip我们能很方便的将同步的一些observable变成异步的,比如

    var source = Rx.Observable.from('hello');

    var source2 = Rx.Observable.interval(100);

    var example = source.zip(source2, (x, y) => x);

    这个例子就能将hello的字母每经过100ms输出一个。

    分割线-------------------------------------------------------------------------------------------------------------------------------------------------------------------

    scan()类似于js的reduce方法,即会保留上一次next的结果值并传入下一次计算的回调函数,作为第一个参数

    var source = Rx.Observable.from('hello')

                .zip(Rx.Observable.interval(600), (x, y) => x);

    var example = source.scan((origin, next) => origin + next, '');

    source : ----h----e----l----l----o|

        scan((origin, next) => origin + next, '')

    example: ----h----(he)----(hel)----(hell)----(hello)|

    buffer()会将一个observable的next输出暂存起来,直到另一个observable传出next时将缓存区内的所有数据通过数组形式传出。

    var source = Rx.Observable.interval(300);

    var source2 = Rx.Observable.interval(1000);

    var example = source.buffer(source2);

    source : --0--1--2--3--4--5--6--7..

    source2: ---------0---------1--------...

                buffer(source2)

    example: ---------([0,1,2])---------([3,4,5])

    bufferTime()则是设定一个缓存周期,每经过这一个周期则将缓存内的数据通过数组传出。

    var source = Rx.Observable.interval(300);

    var example = source.bufferTime(1000);

    bufferCount()则设定一个缓存大小,每当缓存达到大小时将数据输出

    var source = Rx.Observable.interval(300);

    var example = source.bufferCount(3);

    bufferToggle()传入一个Open Observable和一个Close Observable以及一个source Observable,每当Close传出一个

    next时,查找Open的上一个next(),则将这两个next()区间内的所有source的next传出。

    const source$ = Rx.Observable.interval(500);

    const open$ = Rx.Observable.interval(1500);

    const close$ = Rx.Observable.interval(1000);

    const foo$ = source$.bufferToggle(open$, ( ) => {

      return close$;

    });

    /**

    ---0---1---2---3---4---5---6---7---8---9----....    (source)

    -----------1-----------2-----------3--------...      (open)

              --- ---x    --- ---x    --- ---x...      (close)

            bufferToggle(open$, () => close$)

    ------------------([2,3])-----([5.6])-----([8,9])--...

    */

    bufferWhen()类似与buffer(),不过bufferWhen的参数是一个function,他的返回值为关闭buffer的observable

    const open$ = Rx.Observable.interval(1000);

    const click$ = Rx.Observable.fromEvent(document, 'click');

    var w = open$.bufferWhen(( ) => click$);

    w.subscribe(x => console.log(x))

    // 每次点击都能进行一次分组

    // 第二秒点击第一次:[0, 1, 2]

    // 第六秒点击第二次:[3, 4, 5, 6]

    分割线-------------------------------------------------------------------------------------------------------------------------------------------------------------------

    delay()可以延迟observable一开始发送next的时间,也可以传递毫秒数,也可以传递一个时间。

    var source = Rx.Observable.interval(300).take(5);

    var example = source.delay(500);

    var example2 = source.delay(new Date(Date.now() + 500)); //此二式结果相同

    source : --0--1--2--3--4|

            delay(500)

    example: -------0--1--2--3--4|

    delayWhen()和delay相似,但是最大的不同是他会延时每一个next(),而不像delay只会延时第一个next()

    var source = Rx.Observable.interval(300).take(5);

    var example = source

                  .delayWhen(

                      x => Rx.Observable.empty().delay(100 * x * x)

                  );

    source : --0--1--2--3--4|

        .delayWhen(x => Rx.Observable.empty().delay(100 * x * x));

    example: --0---1----2-----3-----4|

    debounce()传入一个debounce observable,每当source observable传出next时,不会立刻将之直接传出,而是将之缓存,

    如果在收到debounce传出的next之前没有收到其他source传出的next,那么将此次缓存的next传出,否则则将新的source next存入缓存,并等待下一次debounce的来临。

    debounceTime()则是一个debounce的简化版,他接收一个时间参数,等同于一个interval Operator创建的observable。

    //疑问:complete是否与next效果相同,在下面例子中在观测前记录Date.now()并在送出next后几率Date.now()会发现时间相差会1.

    var source = Rx.Observable.interval(300).take(5);

    var oDebounce = Rx.Observable.interval(1000);

    var example = source.debounceTime(1000);

    var example2 = source.debounce(() => oDebounce);  //此二式效果相同

    source : --0--1--2--3--4|

            debounceTime(1000)

    example: --------------4| 

    相关文章

      网友评论

          本文标题:RawRxJS笔记

          本文链接:https://www.haomeiwen.com/subject/cnybuftx.html