Javascript 理解rxjs中的SwitchMap
根据开关图的定义 在每次发射时,先前的内部可观测值( 您提供的函数)被取消,新的可观察对象被取消 订阅。你可以通过短语切换到一个新的 可见的 现在,我有一个这样的代码Javascript 理解rxjs中的SwitchMap,javascript,rxjs,reactive-programming,rxjs6,switchmap,Javascript,Rxjs,Reactive Programming,Rxjs6,Switchmap,根据开关图的定义 在每次发射时,先前的内部可观测值( 您提供的函数)被取消,新的可观察对象被取消 订阅。你可以通过短语切换到一个新的 可见的 现在,我有一个这样的代码 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
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()));
结果就是这样
我的问题是,
我发现很难理解这个概念,谢谢你,这是因为RxJS在默认情况下用于异步操作时使用了
setTimeout
和setInterval
函数,这些函数不能保证它们会精确地执行你想要的超时
因此,如果您使用超时5000
和1000
,则无法保证在5s后会首先发生哪些操作。有时外部可观察物先发射,有时内部先发射,但switchMap
对此无能为力
你可以看到时间的不同,例如:
const start = new Date().getTime();
setInterval(() => console.log(new Date().getTime() - start), 1000);
现场演示:
所以有时候延迟是1004秒,有时候是998秒,我想,你错误地认为你的源是在25秒开始发射的,而它是在24秒开始发射的。没有“默认0” 震源在
t0
发射,然后在1s
内部间隔内
将发射。内部间隔
将有5秒时间发出4次或5次,然后从源计时器切换到另一个值。如果源计时器开始在24s
发射,则订阅上获得的第一个值为25s
——此时间隔将发射其第一个值
4次或5次的原因是在RxJS和JS调度中。看看这是怎么回事。详细解释这一点需要更多的研究工作和时间
这是一个大理石图,描绘了mergeMap vs exhaustMap vs switchMap vs concatMap
行为,以便更好地理解:
检查此项。因此,在switchMap中,无论何时调用外部函数,内部函数值都会重置,我的理解是否正确?如果可能的话,你能制作一个弹珠来帮助人们理解switchMap吗?像这样的一个?@LijinDurairaj这显示了什么switchMap
我刚刚发现了这一点,根据这个弹珠,当外部函数发出一个值时,switchMap只发出一个值,它重置了整个内部函数值,我的理解正确吗,如果我错了,请纠正我。我认为,这里的特殊问题不是JS调度器缺少1s间隔,而是RxJS交替使用setInterval
和setTimer
的方式,以及这些异步任务在JS环境中的优先顺序。当JS调度器检查其任务列表时——它将运行所有设置的计时器和间隔,但执行顺序将取决于设置的方式和时间。这是一个顺序交换的结果calls@LijinDurairaj,“重置内部功能”不是思考开关映射的最佳方式。所有\uu Map
运算符都用内部函数返回的值流替换源流上的值。差异是对源流上后续值的反应switchMap
将从先前交换的流中取消订阅,并使用由内部函数生成的新流。除了@martin的回答解释了34s
和39s
上的差距外,我认为,您还错误地假设源在25
第1秒开始发射,而它在24s
开始发射。没有“默认0”,它是从24s
开始的源代码,在25s
第一次发射间隔。您所有使用大理石的示例都非常有用,谢谢
1004
2001
3002
4000
4998
...