Пожалуйста, объясните разницу между RxJS map и switchMap в соответствии с примером - PullRequest
0 голосов
/ 19 октября 2019

Я видел много других сообщений на эту тему, и прочитал официальную (см. Ниже) и полуофициальную документацию, такую ​​как https://www.learnrxjs.io/operators/transformation/switchmap.html,, но я все еще не смог усвоить разницу между "map "и" switchMap ", и я надеюсь уточнить с конкретными примерами ниже.

Примечание в соответствии с официальной документацией RxJS:

Имея в виду мое неполное понимание, я сделал несколько очень простых примеров, см. StackBlitz https://stackblitz.com/edit/rxjs-xpicph?devtoolsheight=60,, но все еще не до конца понимаю, почему некоторые из примеровпроизводят продукцию, которую они делают, так, как они делают.

Во-первых, несколько очень простых string примеров:

// String Example 1

const source = of('World').pipe(
  map(x => `Hello ${x}!`)
);

source.subscribe(x => console.log(`SOURCE (map): ${x}`));

// SOURCE (map): Hello World!

Хорошо, достаточно справедливо, я думаю, что я в основном понимаю это.

  1. "Of" испускает "World" в качестве значения (или излучение все еще является наблюдаемым на этом этапе?) Для "pipe"
  2. "pipe" предоставляет "World" какзначение (или это все еще Observable?) для «сопоставления»
  3. «map» проецирует это (значение? Observable?) в «Hello World», ожидая завершения всех символов, и возвращает это (значение«Observable») для «pipe»
  4. «pipe» затем возвращает Observable.

Следовательно, мы получаем вывод: «Hello World»

// String Example 2

const otherSource = of('World').pipe(
  switchMap(x => `Hello ${x}!`)
);

otherSource.subscribe(x => console.log(`SOURCE (switchMap): ${x}`));

// SOURCE (switchMap): H
// SOURCE (switchMap): e
// SOURCE (switchMap): l
// SOURCE (switchMap): l
// SOURCE (switchMap): o
// SOURCE (switchMap):
// SOURCE (switchMap): W
// SOURCE (switchMap): o
// SOURCE (switchMap): r
// SOURCE (switchMap): l
// SOURCE (switchMap): d
// SOURCE (switchMap): !

Вау! ИЗВИНИТЕ МЕНЯ? ЧТО ПРОСТО ПРОИЗОШЛО?

  1. "Of" испускает 'World' в качестве значения (или излучение все еще является наблюдаемым на этом этапе?) Для "pipe"
  2. "pipe" обеспечивает 'World 'как значение (или это все еще Observable?) Для "switchMap",
  3. "switchMap" проецирует это (значение? Observable?) В "Hello World", но в отличие от "map" недождаться завершения всех символов, прежде чем выводить в "трубу" серию наблюдаемых (или значений?), и будет ли это один наблюдаемый на символ? или это один Observable, который излучает один раз на каждого персонажа?
  4. "pipe" затем возвращает Observable для каждого символа?

ВОПРОС: Что именно здесь происходит под капотом, шаг за шагом в цепях выше?

Давайте перейдем к другому простому набору примеров, а затем, надеюсь,попробуйте связать все вместе:

// OBJECT EXAMPLES

const foo = {
  "first": 1,
  "second": 2
}

// OBJECT EXAMPLE 1

Object.keys(foo).forEach(obj=>of(foo[obj]).pipe(
  map(x=>x*2)
).subscribe(x => console.log(`SOURCE (map): ${x}`)))

// SOURCE (map): 2
// SOURCE (map): 4

ОК, достаточно справедливо. Это кажется довольно простым

// OBJECT EXAMPLE 2

Object.keys(foo).forEach(obj=>of(foo[obj]).pipe(
  switchMap(x=>of(x*2))  // WHY DO WE NEED ANOTHER "of()" HERE? "switchMap(x=>x*2)" DOESN'T COMPILE
).subscribe(x=> console.log(`SOURCE (switchMap): ${x}`)))

// SOURCE (switchMap): 2
// SOURCE (switchMap): 4

Достаточно ясно, но ПОЧЕМУ нам нужно предоставить «(x * 2) для« switchMap »? В STRING ПРИМЕРЕ 2« switchMap », казалось, излучал как сумасшедший и автоматическиобернуть его вывод как Observable (или «pipe» обернуть вывод как Observable?), но в любом случае, «switchMap» и «pipe» не нуждались ни в каких дополнительных «of ()» или какой-либо другой помощи для переноса вывода какObservable, но в OBJECT EXAMPLE 2 нам явно необходимо предоставить второй «of ()», чтобы убедиться, что выходные данные «switchMap» являются наблюдаемыми, иначе код не скомпилируется (но для «map»,нам не нужно предоставлять второе "of ()"). Опять же, шаг за шагом, почему разница?

Итак, подведем итог, я был бы чрезвычайно признателен, если кто-нибудь может объяснить:

  1. В какой момент (ы) в цепочке (ах) в приведенных выше примерах мы имеем дело со значениями (т. Е. Выбросами из наблюдаемых) и в каких точках с наблюдаемыми?
  2. Почему «switchMap» обеспечивает очевидный разборповедение, видимое в STRING EXAMPLE 2?
  3. Почему нам нужно предоставить "of ()" для switchMap в OBJECT EXAMPLE 2, а не в STRING EXAMPLE 2? (И, аналогично, почему «map» не требуется второй «()»?)

Заранее спасибо !!

1 Ответ

1 голос
/ 19 октября 2019
  1. Для ваших примеров операторов это преобразования типов:

    • of: получает параметр типа T, создает одно уведомление типа T, затем завершается
    • map: получает параметр типа T => R, создает уведомление типа R всякий раз, когда получает уведомление типа T
    • switchMapполучает параметр типа T => ObservableLike<R>, создает уведомление типа R всякий раз, когда получает уведомление типа T

Я думаю, что это главная путаница здесь. switchMap имеет функцию проекции, которая ожидает ObservableLike<R> в качестве возвращаемого типа. Важной частью этого утверждения является Observable Подобно .

Это иногда нелогично, но RxJS внутренне преобразует другие типы в Observables, когда это возможно, например:

  • Array или
  • Promise

Когда Array используется в месте, где может быть предоставлено ObservableLike, RxJS обрабатывает массив как поток значений.

Например, скажем, я преобразовал этот массив в наблюдаемый:

from([1, 2, 3])

, что я получу при подписке будет:

// 1
// 2
// 3

И поскольку string является не чем иным, как Array<char>, RxJS пытается преобразовать эту строку в поток ее символов. (char на самом деле не является типом данных в JS, но внутренне строка является массивом)

т.е. они равны:

  • from(['a', 'b', 'c'])
  • from('abc')

Я думаю, что это объясняется с ответом выше. Вам всегда необходимо предоставить ObservableLike для switchMap, но тип string оказывается ObservableLike - просто поток символов.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...