从敕令式到相应式(五)

接着上一节的操作符继承,让我们直奔主题。

组合类操作符

组合类的操作符能够将差别流数据按肯定的划定规矩举行兼并,从而取得所须要的完全数据。

  1. combineLatest

实例要领

将多个输入流组合成一个输出流,输出流上的数据是由每一条输入流上的末了一条数据组合成的数据。

不管什么时间只需输入流上发出了数据,它就会把一切输入流上的最新数据组合成一条新的数据推送到输出流上。症结点在于恣意一条被组合的流发出数据,输出流上都将有新的数据发作。

    -a------b----c-----d------e---|

    --1--2-----3--4-----5---6---|

            combineLatest

    --a1-a2-b2--b3-c3-c4----d4-d5---e5-e6-|

别的它能够吸收一个映照函数作为末了一个参数,一切输入流的值会顺次传入映照函数作为它的参数。

返回 Observable 一条包括一切输入流最新值的流,或许是一切最新值的映照值的流。

示例

const weight = of(70,72,76,79,75);

const height = of(1.76,1.77,1.78);

const bmi = weight.combineLatest(height, (w, h) => w/h*h);

bmi.subscribe(x => console.log('BMI is ' + x);
  1. withLatestFrom

实例要领

将多个输入流组合成一个输出流,输出流上的数据是由每一条输入流上的末了一条数据组合成的,然则组合行动只在源 Observable 发出值时发作,这里的源 Observable 指的是挪用withLatestFrom的实例。也就是说只要当源 Observable 发作值时,才会发作新的值。

    -a-----b--------------c------------d--e---|-->

    ----1-----2-----3--4--------5----|---->

            withLatestFrom

    ------b1------------c4-----------d5--e5---|-->

返回值 Observable 一条包括一切输入流最新值的流,或许是一切最新值的映照值的流。

和combineLatest一样它也能够吸收映照函数作为参数。

示例

const clicks = fromEvent(document, 'click');
const timer = interval(1000);
const result = clicks.withLatestFrom(timer)

result.subscribe(x => console.log(x));
  1. zip

实例要领

假如一切的输入都是流,那末将一切输入流对应位置上的值组合成一个新值,将这个新值作为输出流上的值。另外zip操作符还能够直接运用可转化为流的数据作为参数,比方数组,promise,字符串等。

--a------b------c------d---2--|->

-----e------f------g-----h--|->

            zip

----ae------fb-----gc----hd-|->

返回值 Observable 将各输入流上对应的值组合成新的值发送给输出流或许先经由映照函数处置惩罚后再发送给输出流。

它也能够吸收映照函数作为参数。

示例

const obs1 = from([1,2,3,4]);
const obs2 = from(['a','b','c']);

obs1.zip(obs2)
    .subscribe(v => console.log(v));
const obs = interval(1000);
const promise = new Promise(resolve => {
    setTimeout(() => resolve('hello'), 2000);
});

obs.zip(promise, (obs, promise) => promise + obs)
    .subscribe(v => console.log(v));
  1. merge

实例要领

建立一条能够同时把一切输入流的值推送出去的流。它把多条输入流兼并成一条输入流,一切输入流的值都能够在这条输出流上获得。

    -a----------b----------c---|----->

    ------d---------e----------e----|-->

                merge

    -a----d----b----e-----c----e----|-->

兼并一切输入流的定阅,不管是源 Observable 照样作为参数输入的 Observable,只是把值顺次推送到输出流上,不作任何分外的变动。输出流只要在一切的输入流都完成今后才完成,任何一条输入流上的毛病都将马上推送到输出流上。

返回值 Observable 能够发送一切输入流上的值的Observable。

示例

const clicks = fromEvent(document, 'click');
const timer = interval(1000);
const clicksOrTimer = clicks.merge(timer);

clicksOrTimer.subscribe(x => console.log(x));
  1. forkJoin

静态要领

将输入流的末了一个值兼并后传给输出流。它的效果等同于Promise.all(),因而在你须要多个并发要求都返回效果时能够运用它。

forkJoin能够以参数或数组的情势吸收恣意数目的输入流。假如没有转入输入流,输出流将会马上发出完毕关照。

它会等一切的输入流发出完毕关照,然后发出一个包括一切输入流发出的最终值构成的数组,因而,传入n条输入流,获得的数组中将包括n个元素,每个元素都是从对应递次的输入流上取到的末了一个值。这也就意味着输出流只会发出一个值,紧接着就会发出完毕关照。

为了运用输出流上获取到的数组的长度与输入流的数目保持一致,假如某一个输入流在发出完毕关照之前没有发出过任何有效值,那末输出流也将会马上完毕而且不再发出任何值,只管别的的输入流上可能会发出有效值。反过来,假如有一条输入流一向没有发出完毕关照,输出流也不会发出值,除非别的一条输入像之前形貌的那样只发了完毕关照。总的来说就是为了让输出流发出值,一切的输入流都必需发出完毕关照而且在此之前必需最少发出一个有效值。

假如输入流中的某一条发出了毛病关照,输出流将会马上发出这个毛病关照,而且马上作废对别的流的定阅。

    ----2---3------4----5--|-->

    ----a----b------------d---|-->

                forkJoin

    --------------------------5d|

返回值 Observable 以数组情势获取到的每个输入流的值,或许来自映照函数的值。

能够吸收映照函数作为参数。

示例

const observable = forkJoin(
    of(1, 2, 3, 4),
    of(5, 6, 7, 8)
);

observable.subscribe(
    value => console.log(value),
    err => {},
    () => console.log('This is how it ends!')
);
const observable = forkJoin(
    interval(1000).take(3),
    interval(500).take(4)
);

observable.subscribe(
    value => console.log(value),
    err => {},
    () => console.log('This is how it ends!')
);

转换范例操作符

这里我们重要引见那些能够处置惩罚高阶流的操作符。

  1. map

实例要领

输出流上的值是运用一个映照函数将输入流上的值映照后获得新的值。

    --------1-----------2----------3----------|--->

            map(v => v * 10);

    --------10----------20---------30---------|---->

返回值 Observable 发出映照后的值的流。

示例

fromEvent(document, 'click')
    .map(event => event.clientX)
    .subscribe(v => console.log(v));
  1. mergeMap

实例要领

将一切输入流的值都兼并到一条流上。

    -1-----2-----3---------|-->

    ---2----2----2--|-----> //第一次时的内部流,第2,3次的一样,这个流是直正的输入流

            mergeMap(v => Observable.of(v + 1).repeat(3));

    -2--2--2--3--3--3--4--4--4----|-->

输出流会把一切从映照函数中返回的内部流打平到一条流上。映照函数能够运用输入流的值来天生内部流。

返回值 Observable 一条兼并了一切映照函数天生的内部流的流,内部流上的值都邑在这条流上发出。

示例

of('a','b','c')
    .mergeMap(v => Rx.Observable.interval(1000).map(x => x + v ))
    .subscribe(v => console.log(v));
const source = of('Hello');

const createPromise = v => new Promise(resolve => resolve(`I got ${v} from promise`));

source.mergeMap(
    v => createPromise(v),
    (outValue, innerValue) => `Source: ${outValue},${innerValue}`
)
.subscribe(v => console.log(v));
  1. switchMap

实例要领

在输入流发出值时,把它映照成一条内部流,然后把这条内部流打平成到输出流上,输出流上只会发出近来的内部流上的值。

    -1---------3-----5----|->

    -10---10---10-| // 内部流

            switchMap(v => Observable.from([10,10,10]).map(x => x * v))

    -10---10---10-30---30-50---50---50-|

输出流上的值是由映照函数在输入流的值的基本上天生的内部流所发出的,输出流只允许视察一条内部流,当有新的内部流抵达时,输出流将会作废对之前的内部流的定阅,转而定阅这个最新的内部流,并发出它上面的值。

返回值 Observable 仅从最新的内部流上取值的流。

示例

fromEvent(document, 'click')
    .switchMap(event => interval(1000))
    .subscribe(v => console.log(v));
  1. concatMap

实例要领

将多个流兼并到一条流上,须要守候当前的流完成后才最先兼并下一个,兼并历程按传入的递次举行。

    --1------------3---------5-----------|-->

    --10---10---10--|-->

                concatMap(i => 10*i----10*i---10*i)

    --10---10---10-30---30---30-50---50---50--|->

返回值 Observable 把输入的值经由映照成流后再连接起来的流。

示例

fromEvent(document, 'click')
    .concatMap(event => Rx.Observable.interval(1000).take(3))
    .subscribe(v => console.log(v));
  1. groupBy

实例要领

将输入流上的值按肯定的划定规矩分构成差别的流,然后把这些流发送给输出流,每一条流上都是一组相符雷同前提的值。

----1----2----3----4----5----|->

            groupBy(v => v%2);

-----------------------------|->
    \   \
     \   2---------4---------|
      1------3----------5----|

返回值 Observable 发出分组后的流的高阶流,分组的流都有一个唯一的key,而且该流中的值都是输入流上相符某一前提的值。

示例

of(
    {id: 1, name: 'aze1'},
    {id: 2, name: 'sf2'},
    {id: 2, name: 'dg2'},
    {id: 1, name: 'erg1'},
    {id: 1, name: 'df1'},
    {id: 2, name: 'sf2'},
    {id: 3, name: 'qfs3'},
    {id: 2, name: 'qsg'}
)
.groupBy(v => v.id)
.mergeMap(group => group.reduce((acc,cur) => [...acc, cur],[]))
.subscribe(v => console.log(v))

聚合类操作符

  1. reduce

实例要领

在源 Observable 上运用一个积累函数,当源 Observable 完毕时把积累的值推送给输出流,能够吸收一个初始的积累值。

    --------1-------2-------3---|-->

            reduce((acc,cur) => acc + cur, 0);

    ----------------------------4|

这个操作符的行动与数组的reduce要领雷同。运用一个积累函数来处置惩罚流上的每一值,前一次积累后的值将作为下一次积累的初始值,把经由过程积累获得的最终值推送给输出流。注重,reduce操作符只会在源 Observable 发出完毕关照后发出一个值。

源 Observable 上发出的值都邑被积累函数处置惩罚。假如供应了初始值,这个值将成为全部积累历程的初始值,假如没有供应的话,从源 Observable 发出的第一个值就是全部积累历程的初始值。

返回值 Observable 把源 Observable 上的值都经由积累函数盘算后获得的值作为值发送的流。

示例

const clicksInFiveSeconds = fromEvent(document, 'click')
                            .takeUntil(interval(5000));
const ones = clicksInFiveSeconds.mapTo(1);
const seed = 0;
const count = ones.reduce((acc,cur) => acc + cur, seed);

count.subscribe(v => console.log(v));
  1. scan

实例要领

在输入流上运用一个积累函数,每一次积累的效果都发送给输出流,积累时能够吸收一个可选的初始值。 和reduce操作符相似,差别的是会把每一次积累的效果都发送出去。

返回值 Observable<R> 输出积累值的流。

示例

fromEvent(document, 'click')
    .mapTo(1)
    .scan((acc,cur) => acc + cur, 0)
    .subscribe(v => console.log(v))

操作符就引见到这里,都是一些异常异常异常经常使用的,别的一些没有引见到的并不是没有用,须要的请自行搜刮,经由过程操作符之间的互相组合我们能够完成异常高效便利的数据处置惩罚。

《从敕令式到相应式(五)》

    原文作者:sxlwar
    原文地址: https://segmentfault.com/a/1190000016235806
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞