RxJs的操作符上篇

基本的几个操作符

  • of

    of操作的参数依次输出所有的数据,此时是同步的。

    let stream$ = Rx.Observable.of(1,2,3,4,5)
    
  • from

    from操作符的参数为数组。

    let stream$ = Rx.Observable.from([1,2,3,3,5])
    
  • do

    let stream$ = Rx.Observable.of(1,2,3,4).do(value => console.log(value))
    

    调试Observable使用

  • filter

    过滤操作

    let stream$ = Rx.Observable.of(1,2,3,4,5)
    .do(value => console.log(value))
    .filter((value) => value % 2 === 0);
    
    stream$.subscribe(value => console.log('value',value))
    

高阶Observable操作符

  • flatMap

对比理解 高阶函数 一个函数返回的还是一个函数。首先根据旧Observable的每个值重新产生一个新的Observable,然后flatMap重新将这些metastream的流中流变扁平

let stream$ = Rx.Observable.of(1,2,3)
.flatMap(val => {
    return Rx.Observable.of(val)
            .ajax({url: url})
            .map(e => e.response)
})
  • switchMap

    类似于 mergeMap,但是当源 Observable 发出值时会取消内部 Observable 先前的所有订阅 。

    在实际开发中,常用于级联调用。

    依赖调用意味这调用需要按照顺序执行,调用B必须再调用A执行返回后,

    开发场景:

    • 用户需要先登录
    • 然后获取用户详情
    • 然后可以获取用户订单
    let stream$ = Rx.Observable.of({message:'Login in'})
    .switchMap(result => {
      return Rx.Observable.of({id:1,name:'user'})
    }).switchMap(user => {
      return Rx.Observable.from([
        {id:114,userId:1},
        {id:117,userId:1}
      ])
    })
    
    stream$.subscribe(orders => console.log('Order',orders))
    

组合操作符

  • combineLatest

通常多个的Observable的组合在一起,我们通常需要使用组合操作符来组合两个或者两个以上的source

let source1 = Rx.Observable.interval(100).map(val => 'source1' + val).take(5);

let source2 = Rx.Observable.interval(50).map(val => 'source2' + val).take(2);

let stream$ = Rx.Observable.combineLatest(source1, source2);

stream$.subscribe(data => console.log(data));

业务场景

当你对每一个source的最新值都感兴趣的时候,而对之前的值不感兴趣的时候,可以选择使用使用combineLatest操作符来使用了。

  • concat

    按照顺序来发送Observable

    const getOne$ = Rx.Observable.timer(3000).mapTo({id:1});
    const getTwo$ = Rx.Observable.timer(1000).mapTo({id:2});
    
    Rx.Observable.concat(getOne$,getTwo$).subscribe(res => console.log(res));
    

    concat按照顺序来讲两个或者两个以上的Observable来组合起来,其中是严格的按照顺序来发送结果。

  • merge

    merge将所有的流都合并在一起, 要点是这个操作符组合了几个流,并且就像你在上面所看到的一样,任何像 delay() 这样的时间操作符都是起作用的。 而这个在concat上是不会起作用的。

    const getOne$ = Rx.Observable.of(1).delay(500);
    const getTwo$ = Rx.Observable.of(2,2,3,4,5);
    
    const merge$ = Rx.Observable.merge(getOne$,getTwo$).subscribe(value => console.log(value));
    
  • forkJoin

    Rxjs版本的Promise.all 方法,别让我知道直到所有的 Observables 都完成了,然后再一次性的给我所有的值。(以数组的形式)

    const getOne$ = Rx.Observable.timer(3000).mapTo({id:1});
    const getTwo$ = Rx.Observable.timer(1000).mapTo({id:2});
    
    Rx.Observable.forkJoin(getOne$,getTwo$).subscribe(results => console.log(results));
    
  • zip

    采用的是以列为基础连接值的方式来组合Observable, 如果最后一个参数是一个函数的话则将几个Observable的值都提取出来给函数传参来处理。 依次从每一个Source的相同位置获取值, 一般返回为数组。如果没法凑齐一组则抛弃其他的值。

    常规的用法

    const one$ = Rx.Observable.of(1,2,3);
    const two$ = Rx.Observable.of(4,5);
    const three$ = Rx.Observable.of(6,7);
    
    Rx.Observable.zip(one$,two$,three$).subscribe(value => console.log(value));
    

    zip带参数的使用方法

    const name$ = Rx.Observable.of('finch','wukong','zheng');
    const age$ = Rx.Observable.of(12,15,18);
    const address$ = Rx.Observable.of('shenzhen','wuhan','HK');
    
    Rx.Observable.zip(name$,age$,address$,(name,age,address) => ({name,age,address})).subscribe(value => console.log(value));
    

时间操作符

  • timer

    1. 参数为一个

      const getValue$ = Rx.Observable.timer(500);
      getValue$.subscribe(value => console.log(value));
      

      延迟发送一个数据,然后结束所有的数据。

    2. 参数为两个

      const getValue$ = Rx.Observable.timer(2000,100);
      getValue$.subscribe(value => console.log(value));
      // 首先延迟2S发送一个 然后每隔0.1S发送一个数据
      
  • Interval

    因为这个操作符会不停地生成值,所以倾向于和 take() 操作符一起使用,这样可以在调用它之前限制生成值的数量,就像这样:

    const getValue$ = Rx.Observable.interval(100).take(5)
    

    每隔0.1s发出一个值 然后获取其中的前五个

  • delay

    延迟发送Source每一个的数据。

    const getValue$ = Rx.Observable.interval(100).take(5);
    getValue$.delay(500).subscribe(value => console.log(value));
    
  • debounceTime

    Debounce 是一个已知的概念,特别是当你敲击键盘的时候。就像是在说,我们不在乎你的每次敲击键盘,但是一旦你停止打字后的一段时间是我们所关心的。

    业务场景

    在GUI编程中,比较常见的快速双击按钮是一个比较常见的功能需求,通常为了用户体验我们需要将过于快速的输入省略,直到用户停止输入然后我们才开始接下来的操作。

    const input = document.getElementById('input');
    
    const example = Rx.Observable
      .fromEvent(input, 'keyup')
      .map(i => i.currentTarget.value);
    
    // 在两次敲击键盘事件之间,有0.5秒的等待时间,如果时间小于0.5秒则丢弃前一个敲击键盘事件
    const debouncedInput = example.debounceTime(500);
    
    const subscribe = debouncedInput.subscribe(val => {
      console.log(`Debounced Input: ${val}`);
    });
    

    上面的代码只会输出一个值,值来源于 input 表单,在你停止打字后的500毫秒后,才值得它报告一下,也就是发出一个值。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容