rxjs中的flatMap,mergeMap,switchMap和concatMap? [英] flatMap, mergeMap, switchMap and concatMap in rxjs?

查看:385
本文介绍了rxjs中的flatMap,mergeMap,switchMap和concatMap?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人,请以Javascript的角度解释SwitchMap和FlatMap的区别(角度角度,rxjs 5)

Someone, please explain the difference between SwitchMap and FlatMap in terms of Javascript ( in angular perspective, rxjs 5)

以我的理解.

SwitchMap 仅发出最新的可观察值并取消以前的可观察值.

SwitchMap only emits the latest observable value and cancel previous observable.

flatMap 收集所有单个可观测值,并在单个数组中返回所有可观测值,而无需关心可观测的顺序.异步工作.

flatMap collects all individual observable and returns all observables in a single array without caring the order of observable. works asynchronously.

concatMap 保留顺序并发出所有可观察的值,同步工作

concatMap preserve the order and emits all observable value, works synchronously

是吗?

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

how does mergeMap works differently from above?

有人,请举例说明.

推荐答案

@ZahiC,很酷的答案-我喜欢在代码示例中使用功能组合.如果可以的话,我想借用它来说明一些使用定时观测值的额外要点.

@ZahiC, cool answer - I like the use of functional composition in the code sample. If I may, like to borrow it to illustrate a couple of extra points using timed observables.

这些运算符都是转换运算符,例如map(),它们的共同特点是可观察到的外部内部.关键区别在于外部可观察控制内部可观察的方式.

These operators are all transformation operators like map(), the common feature is they have an outer and inner observable. The key difference is the way the outer observable controls the inner observable.

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

To contrast them, my code sample runs them in pairs, outputting values in the form [outerValue,innerValue]. I have added intervals to the test, and changed the inner delay so that there's some overlap in timing (formula used is delay((5-x)*200)).

这两个都输出所有值,不同之处在于排序.

These both output all values, the difference is the ordering.

mergeMap-按内部可观察顺序排序
[0,0],[1,0],[0,1],[2,0],[1,1],[3,0],[2,1],[4,0],[3 ,1],[4,1]

mergeMap - Order by inner observable
[0,0],[1,0],[0,1],[2,0],[1,1],[3,0],[2,1],[4,0],[3,1],[4,1]

concatMap-按外部可观察顺序排序
[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1],[4 ,0],[4,1]

concatMap - Order by outer observable
[0,0],[0,1],[1,0],[1,1],[2,0],[2,1],[3,0],[3,1],[4,0],[4,1]

从输出中,可以在序列中延迟mergeMap外层发射,但是concatMap遵循严格的外层发射序列.

From the output, mergeMap outer emit can be delayed in the sequence, but concatMap follows strict outer emit sequence.

这两个油门输出.

switchMap-按最后一个油门
[3,0],[4,0],[4,1]

switchMap - Throttle by last
[3,0],[4,0],[4,1]

exhaustMap-先按油门
[0,0],[0,1],[4,0],[4,1]

exhaustMap - Throttle by first
[0,0],[0,1],[4,0],[4,1]

从输出中,switchMap会限制所有不完整内部发出的内容,而exhaustMap会跟随发出声音的内容直到较早的内容完成为止.

From the output, switchMap throttles any incomplete inner emits, but exhaustMap throttles following emits until the earlier ones complete.

我之所以这样说是因为switchmap经常用于应该真正使用mergeMap的SO答案中.

I threw this in because switchmap is often used in SO answers where really mergeMap should be used.

mergeMap-按内部可观察顺序排序
[0,0],[1,0],[0,1],[2,0],[1,1],[3,0],[2,1],[4,0],[3 ,1],[4,1]

mergeMap - Order by inner observable
[0,0],[1,0],[0,1],[2,0],[1,1],[3,0],[2,1],[4,0],[3,1],[4,1]

switchMap-按最后一个油门
[3,0],[4,0],[4,1]

switchMap - Throttle by last
[3,0],[4,0],[4,1]

主要结论是,switchMap输出是不可预测的,具体取决于内部可观察到的时间,例如,如果内部是 http get ,则结果可能取决于连接速度.

The main takeaway is that the switchMap output is unpredictable depending on the timing of the inner observable, e.g if the inner is an http get the results can depend on connection speed.

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));

.examples > div {
  cursor: pointer;
  background-color: #4CAF50;
  color: white;
  padding: 7px 16px;
  display: inline-block;
}

<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>

这篇关于rxjs中的flatMap,mergeMap,switchMap和concatMap?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆