Понимание SwitchMap в rxjs - PullRequest
       85

Понимание SwitchMap в rxjs

3 голосов
/ 05 апреля 2019

согласно определению switchMap

В каждом излучении предыдущая внутренняя наблюдаемая (результат функции, которую вы предоставили) отменяется, и новая наблюдаемая подписывается.Вы можете запомнить это, переключившись на новую наблюдаемую фразу.

Теперь у меня есть такой код

const source = timer(0, 5000).pipe(map(x=>`${x}`));
const example = source.pipe(switchMap((f) => interval(1000).pipe(map(y=>`f${f}-s${y}`))),take(20));
const subscribe = example.subscribe(val => console.log(val+' '+ new Date().getSeconds()));

, и в результате получается

enter image description here

мой вопрос:

  1. 25-я секунда - внешняя функция вызывается, а внутренняя функция еще не запущена, поэтомупоследнее значение внешней функции равно 0, а внутренняя функция также равна 0 в качестве значения по умолчанию, поскольку оно еще не имеет значения f0-s0 25

  2. 26-я секунда -внутренняя функция вызывается, и в идеале значение должно быть 0, так как функция вызывается только в первый раз, но это 1, т.е. f0-s1 26

  3. 30 секунда - вызывается внешняя функция, которая сбрасывает значение внутренней функции до 0, т.е. f1-s0 30

  4. почему внутренняя функция была сброшена на 35-й секунде, осталось еще 1 секунда

ссылка на стек

Мне очень трудно понять концепцию, спасибо

Ответы [ 2 ]

5 голосов
/ 05 апреля 2019

Это потому, что RxJS по умолчанию для асинхронных действий использует функции setTimeout и setInterval, которые не гарантируют, что они достигнут именно того времени ожидания, которое вы хотите.

Так что, если вы используете тайм-ауты 5000 и 1000, тогда не гарантируется, какое из действий произойдет первым через 5 с. Иногда внешний Observable излучает первым, а иногда внутренний излучает первым, но switchMap ничего не может с этим поделать.

Вы можете видеть, как разное время может быть, например. это:

const start = new Date().getTime();
setInterval(() => console.log(new Date().getTime() - start), 1000);

Демонстрация в реальном времени: https://stackblitz.com/edit/typescript-urep5j

1004
2001
3002
4000
4998
...

Так что иногда задержка составляет 1004, а иногда просто 998.

2 голосов
/ 05 апреля 2019

Я думаю, вы ошибочно полагаете, что ваш источник начал излучать с 25s секунды, тогда как он начинался с 24s.И нет никакого «по умолчанию 0».

Источник излучает в t0, затем в 1s внутренний interval будет излучать.Внутренний interval будет иметь 5 секунд для излучения 4 или 5 раз, прежде чем вы переключитесь на другое значение из источника timer.Если ваш источник timer начал излучать с 24s, то первое значение, которое вы получите при подписке, будет 25s - когда interval выдаст свое первое значение.

Причина 4 или 5 время в RxJS и JS.Смотрите stackblitz для грубого примера того, что может происходить.Детальное объяснение этого заняло бы больше исследовательских усилий и времени .

Вот мраморная диаграмма, изображающая поведение mergeMap vs exhaustMap vs switchMap vs concatMap, чтобы лучше понять:

mergeMap vs exhaustMap vs switchMap vs concatMap

Проверьте это объединить карту против выхлопной карты против карты-переключателя против игровой площадки concatMap .

...