switchMap Странное поведение

Я пытаюсь понять консольный вывод следующего кода. Я ожидал, что он будет поддерживать лог от 0 до 9 каждые 500 мс, а затем снова начинать с 0 (и заканчивать с 9).

Но дело в том, что в первый раз консольный журнал будет только 0-9, а затем выводится 0 - 8 с 1-секундной паузой на 8, а затем снова начинается с 0.

Мой вопрос

  1. Почему 9 только появился один раз?
  2. Почему на 8 секунд 1 (вместо 500 мс) пауза?

Поскольку наблюдаемая исходная точка излучает каждые 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 ответа

Решение

Почему 9 только появился один раз?

В моем случае 9 вообще не показывается. Итак, я думаю, это может быть какая-то неточность во времени? Это туго - теоретически interval начинается немного позже, чем таймер. Поэтому он печатает только 9 значений (0-8).

Почему на 8 секунд 1 (вместо 500 мс) пауза?

8 печатается на 4500ms. Когда таймер достигает 5000 мс (что занимает 500 мс с 8), он раскручивает новый interval, Новый интервал будет излучаться через 500 мсек. Следовательно, задержка 1 с между ними.

Если напечатано 9, я бы ожидал, что задержка составит всего 500 мс. Но опять же - в моем случае 9 никогда не печатается.

Поскольку таймер не настолько точен, это проблема цикла событий 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
Другие вопросы по тегам