首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >flatMap,mergeMap,switchMap和concatMap?

flatMap,mergeMap,switchMap和concatMap?
EN

Stack Overflow用户
提问于 2018-04-06 18:02:54
回答 8查看 78.3K关注 0票数 112

有人,请解释一下SwitchMap和FlatMap在Javascript上的区别(从角度上看,rxjs 5)。

据我理解。

SwitchMap只发布最新的可观测值,并取消以前的可观测值。

flatMap收集所有单个可观测数据,并在一个数组中返回所有可观测数据,而不关心可观测的顺序。异步工作。

concatMap保持顺序并发出所有可观测值,同步工作。

是那么回事吗?

mergeMap是如何与上面的工作方式不同的?

有人,请举例说明。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2018-04-06 22:47:51

先前的回答上拿来这个

  • flatMap/mergeMap -为任何源项立即创建一个可观察的,所有以前的可观测值都保持存活。注flatMapmergeMap的别名,flatMap将在RxJS 8中删除。
  • concatMap --在创建下一个可观察到的
  • switchMap -对于任何源项,完成以前的可观察性并立即创建下一个
  • exhaustMap -源项被忽略,而前面的可观测项未完成。

下面是一个示例,说明当源是直接项(0、1、2、3、4)时,每个操作符的行为,而map函数创建了一个可观察到的方法,将每个项目延迟500 is:

代码语言:javascript
复制
const { mergeMap, flatMap, concatMap, switchMap, exhaustMap } = Rx.operators;

const example = operator => () =>
  Rx.Observable.from([0,1,2,3,4])
  .pipe(
    operator(x => Rx.Observable.of(x).delay(500))
  )
  .subscribe(console.log, () => {}, () => console.log(`${operator.name} completed`));

const mm = example(mergeMap);
const fm = example(flatMap);
const cm = example(concatMap);    
const sm = example(switchMap);
const em = example(exhaustMap);
代码语言:javascript
复制
.examples > div {
  cursor: pointer;
  background-color: #4CAF50;
  color: white;
  padding: 7px 16px;
  display: inline-block;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.8/Rx.js"></script>

<div class='examples'>
  <div onClick='mm()'>mergeMap </div>
  <div onClick='fm()'>flatMap</div>
  <div onClick='cm()'>concatMap</div>
  <div onClick='sm()'>switchMap</div>
  <div onClick='em()'>exhaustMap</div>
</div>

票数 175
EN

Stack Overflow用户

发布于 2019-05-03 09:25:11

在位于5 5ms10 5ms20 5ms的源流下面的大理石图中,*将映射为timer(0, 3),限制为3种排放:

在这里播放这个大理石图:"mergeMap vs exhaustMap vs switchMap vs concatMap“

我已经有了所有这些很棒的答案,我想增加一个更直观的解释。

希望它能帮到别人

票数 84
EN

Stack Overflow用户

发布于 2018-04-08 21:46:01

@ZahiC,酷答案-我喜欢在代码示例中使用函数组合。如果可以的话,我想借用它来说明几个额外的点,使用时间上的可观测值。

外部、内部和控制

这些操作符都与变换算子类似,它们的共同特点是它们有一个外部内部。关键的区别在于外部可观测控制内部可观测性的方式。

为了对比它们,我的代码示例成对地运行它们,在表单[outerValue,innerValue]中输出值。我增加了测试的时间间隔,并更改了内部延迟,以便在时间上有一些重叠(使用的公式是delay((5-x)*200))。

mergeMap对concatMap

这两个输出值都是,区别是排序

mergeMap -内部可观测阶 0,0,1 0,0,0,1,2,0,1,3,2,1,3,3,4 concatMap -外部可观测阶数 0,0,0,1,1,1,1,1,2,0,2,3,0,3,3,1,4,0,4,1

从输出结果来看,mergeMap外部发射可以在序列中延迟,但是concatMap遵循严格的外部发射序列。

switchMap对exhaustMap

这两者都是节流输出。

switchMap -最后一个节流阀 3,0,4,0,4,1 exhaustMap -第一节流阀 0 0,0,0,1,4,0,4,1

从输出中,switchMap控制所有不完整的内部发射,但exhaustMap节流跟随发射,直到之前的完成。

mergeMap对switchMap

我加入了这一点,因为在真正应该使用mergeMap的答案中经常使用开关映射。

mergeMap -内部可观测阶 0,0,1 0,0,0,1,2,0,1,3,2,1,3,3,4 switchMap -最后一个节流阀 3,0,4,0,4,1

主要的优点是unpredictable输出是switchMap,这取决于内部可观察到的时间,例如,如果内部是http ,则结果可能取决于连接速度。

代码语言:javascript
复制
console.clear()
const { mergeMap, flatMap, concatMap, switchMap, exhaustMap, delay, map, take, toArray } = Rx.operators;

const note = {
  mergeMap:  'Order by inner observable', 
  concatMap: 'Order by outer observable', 
  switchMap: 'Throttle by last', 
  exhaustMap: 'Throttle by first', 
}
const title = (operator) => {
  const opName = operator.name.replace('$1','')
  return `${opName} - ${note[opName]}`
}
const display = (x) => {
  return map(y => `[${x},${y}]`)
}
const inner = (x) => Rx.Observable.timer(0,500)
.pipe(
  delay((5-x)*200),
  display(x),
  take(2)
)

const example = operator => () => {
  Rx.Observable.interval(500).take(5)
  .pipe(
    operator(x => inner(x)),
    toArray(),
    map(vals => vals.join(','))
  )
  .subscribe(x => {
    console.log(title(operator))
    console.log(x)
  });
};

const run = (fn1, fn2) => {
  console.clear()
  fn1()
  fn2()
}
const mmVcm = () => run(example(mergeMap), example(concatMap));
const smVem = () => run(example(switchMap), example(exhaustMap));
const mmVsm = () => run(example(mergeMap), example(switchMap));
代码语言:javascript
复制
.examples > div {
  cursor: pointer;
  background-color: #4CAF50;
  color: white;
  padding: 7px 16px;
  display: inline-block;
}
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.8/Rx.js"></script>

<div class='examples'>
  <div onClick='mmVcm()'>mergeMap vs concatMap </div>
  <div onClick='smVem()'>switchMap vs exhaustMap</div>
  <div onClick='mmVsm()'>mergeMap vs switchMap </div>
</div>

票数 49
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49698640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档