switchMap Странное поведение - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь понять вывод следующего кода консоли.Я ожидал, что он будет поддерживать лог 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 ]

0 голосов
/ 29 января 2019

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

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

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

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

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

0 голосов
/ 29 января 2019

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