根据switchMap的定义
在每次发射时,前一个内部observable(您提供的函数的结果)被取消,并且新的observable被订阅。您可以通过短语切换到新的可观察对象来记住这一点。
现在,我有一个像这样的代码
const source = timer(0, 5000).pipe(map(x=>`${x}`));
const example = source.pipe(switchMap((f) => interval(1000).pipe(map(y=>`f${f}-s${y}`))),take(20));
const subscribe = example.subscribe(val => console.log(val+' '+ new Date().getSeconds()));
结果是这样的
我的问题是,
我觉得很难理解这个概念,谢谢
我想,你错误地假设你的源码开始在25s
排放第二,而它开始于24s
。并且没有“默认0”。
来源在t0
发出,然后在1s
内部interval
将发出。在您从源interval
切换到另一个值之前,内部timer
将有5秒钟发出4或5次。如果你的源timer
开始在24s
发射,那么你将获得订阅的第一个值是25s
- 当interval
将发出它的第一个值。
4或5次的原因是在RxJS和JS调度中。看看stackblitz for a rough example可能会发生什么。详细解释这将需要更多的研究工作和时间。
下面是一张描绘mergeMap vs exhaustMap vs switchMap vs concatMap
行为的大理石图,以便更好地理解:
检查这个mergeMap vs exhaustMap vs switchMap vs concatMap playground。
这是因为默认情况下,异步操作的RxJS使用setTimeout
和setInterval
函数,这些函数不能保证它们能够完全实现所需的超时。
因此,如果您使用超时5000
和1000
,则无法保证哪些操作将在5s后首先发生。有时外部Observable首先发射,有时内部发射,但switchMap
无法做任何事情。
你可以看到时间的不同,例如。这个:
const start = new Date().getTime();
setInterval(() => console.log(new Date().getTime() - start), 1000);
现场演示:https://stackblitz.com/edit/typescript-urep5j
1004
2001
3002
4000
4998
...
所以有些人延迟是1004
,其他时候只是998
。