switchMap Странное поведение
Я пытаюсь понять консольный вывод следующего кода. Я ожидал, что он будет поддерживать лог от 0 до 9 каждые 500 мс, а затем снова начинать с 0 (и заканчивать с 9).
Но дело в том, что в первый раз консольный журнал будет только 0-9, а затем выводится 0 - 8 с 1-секундной паузой на 8, а затем снова начинается с 0.
Мой вопрос
- Почему 9 только появился один раз?
- Почему на 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