0

我试图理解以下代码的控制台输出。我期待它会每 500 毫秒控制台记录 0 到 9,然后再次以 0 重新开始(最终以 9 结束)。

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

我的问题是

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

由于源 observable 每 5 秒发射一次,而内部 observable 每 500ms 发射一次,它应该有足够的时间让内部 observable 发射 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));
4

2 回答 2

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
于 2019-01-29T09:27:49.383 回答
1

为什么9只出现一次?

在我的情况下,根本没有显示 9。所以我想这可能是某种时间不准确?这很紧——理论上interval比计时器开始晚一点。因此它只打印 9 个值 (0-8)。

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

8 以 4500 毫秒打印。当计时器达到 5000 毫秒(从 8 开始需要 500 毫秒)时,它会启动新的interval. 新的间隔将在另一个 500 毫秒后发出。因此,这些之间有 1 秒的延迟。

如果打印了 9 个,我预计延迟只有 500 毫秒。但同样 - 在我的情况下 9 从不打印。

于 2019-01-29T09:27:58.253 回答