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()));
结果就是这样

我的问题是,

  • 25秒-调用外部函数而内部函数尚未触发,因此外部函数的最新值为0,内部函数也为0作为默认值,因为它还没有值f0-s0 25

  • 26秒-调用内部函数,理想情况下,该值应为0,因为该函数刚被第一次调用,但它为1,即f0-s1 26

  • 第30秒-调用外部函数,将内部函数值重置为0,即f1-s0 30

  • 为什么内部功能在第35秒被重置,它还剩下1秒


  • 我发现很难理解这个概念,谢谢你,这是因为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
    ...