Использование concat внутри mergeMap - PullRequest
0 голосов
/ 28 сентября 2018

Мне трудно понять, что связано с использованием функции concat внутри оператора mergeMap.

В документации для concat написаночто

Вы можете передать либо массив Observables, либо поместить их непосредственно в качестве аргументов.

Когда я помещаю Observables непосредственно в качестве аргументов, как в следующем примере,Я правильно получаю 20 и 24 в консоли.

of(4)
  .pipe(
    mergeMap(number => concat(of(5 * number), of(6 * number)))
  )
  .subscribe(value => console.log(value));

Но когда я ставлю их в виде массива, то в консоли я получаю Observables, а не их значения:

of(4)
  .pipe(
    mergeMap(number => concat([of(5 * number), of(6 * number)]))
  )
  .subscribe(value => console.log(value));

Вот живая версия в Stackblitz.

Есть идеи, почему это так?Разве оба примера не должны работать одинаково?

1 Ответ

0 голосов
/ 28 сентября 2018

Эти два сценария различны, и они не должны работать одинаково.concat принимает Observables в качестве аргументов, и он будет последовательно подписываться на эти потоки и подписываться на следующий Observable только после завершения предыдущего.Каждый оператор или метод создания возвращает Observable.Это означает, что в первом примере, когда вы используете concat, он возвращает Observable, который испускает 20, а затем 24.Поскольку вы имеете дело с вложенным Observable, вы должны использовать mergeMap, который подпишется на результирующее Observable, возвращаемое concat.

Теперь во втором примере, если вы передадите массив, concatпреобразует это (используя from() внутри) в Observable, который испускает 2 значения, и эти значения снова становятся Observables.Таким образом, у вас есть 3 уровня вложенности здесь.Первый - это самый внешний Observable, источник, который of(4), второй уровень - это тот, который вы отображаете внутри вашего mergeMap, а третий во втором примере - это Observables внутри вашего массива.Дело в том, что вы выравниваете уровни только до уровня 2, но не до 3-го уровня.Опять же, во втором примере Observable, возвращаемое mergeMap, испускает два Observable, но это только прокси, а не значения, испускаемые этими Observable.Если вы также хотите подписаться на них, вы можете подключиться к другому mergeMap, например так:

concatArray() {
  of(4)
    .pipe(
      mergeMap(number => concat([of(5 * number), of(6 * number)])),
      mergeMap(x => x)
    )
    .subscribe(value => console.log(value));
}

Другой способ - распространить массив так, чтобы concat не получалобъект, который ArrayLike, а точнее Observables напрямую:

concatArray() {
  of(4)
    .pipe(
      mergeMap(number => concat(...[of(5 * number), of(6 * number)]))
    )
    .subscribe(value => console.log(value));
}

Оба распечатают:

20
24

Я надеюсь, что это делает это немного более ясным и описывает различия междупервый и второй пример.

...