简单学习rxjs中map、concatAll、concatMap、mergeAll、mergeMap、switchAll、switchMap

1、map

map和javascript中的数组的map方法类似,不过这里为了结合下面的demo,我先用map做一个我们不想要的效果:

  const getData = (param) => {
    return of(`return: ${param}`).pipe(
      delay(Math.random() * 1000)
    )
  };


  from([1, 2, 3, 4,5])
    .pipe(
      map(param => getData(param)),
    )
    .subscribe(val => console.log(val));

控制台输出是:
在这里插入图片描述
getData返回的是observable, 但是如果我想拿到返回的observable里面的值,怎么办呢?就是下面的方法了:

2、concatAll

javascript中数组也有一个方法叫做concat,实现的效果类似吧。

Flattens an Observable-of-Observables by putting one inner Observable after the other.

在这里插入图片描述

from([1, 2, 3, 4, 5])
    .pipe(
      map(param => getData(param)),
      concatAll()  // 比上个例子多出的部分
    )
    .subscribe(val => console.log(val));

输出结果是:

return: 1
return: 2
return: 3
return: 4
return: 5

多跑几次代码,每次都是这个输出顺序。
和上个demo相比,直接拿到了getData返回的observable中的值,因为concatAll有个flatten效果。不过可以把map和concatAll直接结合成一个操作符, 就是下面这个:

3、concatMap

Maps each value to an Observable, then flattens all of these inner Observables using concatAll.

这个操作符可以传递好几个参数,我学的比较简单,就用一个的:

from([1,2,3,4,5])
   .pipe(
     concatMap(param => getData(param))
   )
   .subscribe(val => console.log(val));

4、mergeAll

先跑代码,再分析吧:

from([1, 2, 3, 4, 5])
    .pipe(
          map(
             item => getData(item)
          ),
          mergeAll()
    )
    .subscribe(v => console.log(v));

多跑几次,就会发现每次的输出的顺序都是不一致的,并不是按照1 2 3 4 5的顺序输出的, 这点和concatAll不一致。为什么呢?

在这里插入图片描述
从上面的marble图可以看到,mergeAll接受2个observable,每个observable发射出来值之后,mergeAll之后产生的observable就直接emit了。而从concatAll的marble图可以看出,他等到发射完毕了先进入的observable发射出的所有值时候,才会发射后进入的observable发射的值。

其实也可以实现concatAll的效果,只要 mergeAll(1) 就可以了

map和mergeAll也可以和成一个操作符,就是下面这个了

5、mergeMap(又叫flatMap)

Maps each value to an Observable, then flattens all of these inner Observables using mergeAll.

  from([1, 2, 3, 4,5])
    .pipe(
      mergeMap(param => getData(param))
    )
    .subscribe(val => console.log(val));

6、switchAll

喜新厌旧

switch to a new observable.

it behaves like mergeAll. However, when a new inner Observable is emitted, switch unsubscribes from the earlier-emitted inner Observable and subscribes to the new inner Observable and begins emitting items from it.

在这里插入图片描述

from([1,2,3,4,5]).pipe(
    map(param => getData(param)),
    switchAll()
  ).subscribe(val => console.log(val));

每次运行的结果都是:

return 5

map之后产生的五个observable, 经过switchAll之后,由于五个observable的delay不同,所以还没来得及发射数据,就被最后的observable给‘踢’掉了。
和上面的差不多,map之后switchAll也可以合并成一个操作,就是下面的:

7、switchMap

     from([1,2,3,4,5])
     .pipe(
           switchMap(param => getData(param))
     )
     .subscribe(val => console.log(val));

结果和上面的是一样的了。

7、rxdart中的map

直接上代码:

import 'package:rxdart/rxdart.dart';
const a = [1, 2, 3, 4, 5];
void main() {
  Observable(Stream.fromIterable(a))
      .map((item) => item + 10)
      .listen(print);
}

安装rxdart需要这么搞一下,在pubspec.yaml中加入:
dependencies:
rxdart: 0.21.0

参考文献:
https://medium.com/@luukgruijs/understanding-rxjs-map-mergemap-switchmap-and-concatmap-833fc1fb09ff
http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-switchMap
http://semlinker.com/rxjs-merge-map-and-switch-map/

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值