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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgrbsbf/article/details/88369228

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

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/

猜你喜欢

转载自blog.csdn.net/zgrbsbf/article/details/88369228