为什么 Rxjs switchMap 只输出 of() 源 observable 的最后一个值?

问题描述 投票:0回答:2

下面是 2 个片段,第一个带有

map
,第二个带有
switchMap

map
的工作原理是可以理解的:

of('foo', 'bar')
  .pipe(map((val) => sanitizer(val)))
  .subscribe((val) => console.log('value:', val));

function sanitizer(val: string) {
  return val;
}

输出:

value: foo
value: bar

现在使用

switchMap
时,仅输出最后一个值。这是为什么?

我的假设是

map
用于同步操作,
switchMap
用于异步操作(返回可观察值/承诺)。

of('foo', 'bar')
  .pipe(switchMap((val) => sanitizer(val)))
  .subscribe((val) => console.log('value:', val));

async function sanitizer(val: string) {
  return val;
}

输出:

value: bar

这是 stackblitz:https://stackblitz.com/edit/rxjs-acjgon?file=index.ts

javascript angular typescript rxjs
2个回答
0
投票

switchMap
取消之前的可观察值(切换到新的),当新值进来时,如果你想保留顺序,那么使用
concatMap
- 这将首先解析第一个可观察值,然后解析第二! (顺序被保留)(concatMap 的特殊属性)

of
立即发出一个又一个,所以第一个没有得到解决。

of('foo', 'bar')
  .pipe(concatMap((val) => sanitizer(val)))
  .subscribe((val) => console.log('value:', val));

async function sanitizer(val: string) {
  return val;
}

0
投票

来自 switchMap 上的

RxJS 文档

将每个源值投影到一个 Observable,该 Observable 合并到输出 Observable 中,仅从最近投影的 Observable 发出值。

请记住,RxJS 实现了基于推送的模型。当

switchMap
收到一个值时,它会立即开始处理它。如果在处理期间有新值到达,
switchMap
将放弃当前的
Observable
Promise
并切换到新的。

此行为在事件更新频繁的场景中特别有用,例如在搜索框中键入内容,其中只有最新的输入才能获取结果:

input$.pipe(
  switchMap(input => http.get(`/api/search?q=${input}`))
).subscribe(result => console.log(result));

但是,对于必须按顺序处理每个输入的情况,

concatMap
更合适,因为它会不间断地一个接一个地处理值。

希望这有帮助!

© www.soinside.com 2019 - 2024. All rights reserved.