switchMap奇怪的行为

时间:2019-01-29 09:07:31

标签: rxjs switchmap

我试图了解以下代码的控制台输出。我原以为它会每500ms记录一次0到9的日志,然后再次从0开始(最后以9结束)。

但是事实是,它只会在第一次控制台日志0-9,然后输出变为0-8,在8处暂停1秒,然后再次从0开始。

我的问题是

  1. 为什么9只出现一次?
  2. 为什么在8上有1秒(而不是500ms)的暂停?

由于源可观察物每5秒钟发射一次,内部可观察物每500毫秒发射一次,因此内部可观察物应该有足够的时间发射0到9,并且不应在8时暂停。

这是stackblitz上的相同代码: https://stackblitz.com/edit/typescript-eb62ap?file=index.ts&devtoolsheight=100

// RxJS v6+
import { timer, interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';

//emit immediately, then every 5s
const source = timer(0, 5000);
//switch to new inner observable when source emits, emit items that are emitted
const example = source.pipe(switchMap(() => interval(500)));
//output: 0,1,2,3,4,5,6,7,8,9...0,1,2,3,4,5,6,7,8
const subscribe = example.subscribe(val => console.log(val));

2 个答案:

答案 0 :(得分:2)

因为计时器不够准确,这就是NodeJS事件循环和计时器API的问题。

将要打印9的最后一个间隔将要执行,但是timer(0, 5000)已经到了时间。

您可以尝试稍微增加timer以便打印出9

const source = timer(0, 5100); //add some time
const example = source.pipe(switchMap(() => interval(0,500)));

或使用timer代替interval,这样它将立即执行以查看9的打印状态

const source = timer(0, 5000);
const example = source.pipe(switchMap(() => timer(0,500))); //use timer

答案 1 :(得分:1)

为什么9只出现一次?

在我的情况下,根本没有显示9。所以我想可能是时间上的某种误差?这很严格-理论上interval的启动比计时器晚一点。因此,它仅打印9个值(0-8)。

为什么在8上有1秒(而不是500ms)的暂停?

8印刷时间为4500毫秒。当计时器达到5000毫秒(从8开始需要500毫秒)时,它将旋转新的interval。新的间隔将在另一个500ms后发出。因此,两者之间会延迟1秒。

如果打印9张,我希望延迟仅为500ms。但是,再次-在我的情况下,从不打印9。