DevGang
Авторизоваться

Где разместить RxJs оператор take(1)?

Имеет ли значение, помещаем ли мы take(1) в начало или конец наблюдаемой цепочки?

Глядя на следующие два (псевдо) примера наблюдаемой цепочки RxJ, имеет ли значение, куда мы помещаем оператор take?

Пример 1:

.pipe(
  take(1),
  switchMap(…)
)

Фрагмент кода наблюдаемой цепочки с использованием оператора take перед оператором switchMap

Пример 2:

.pipe(
  switchMap(…),
  take(1)  
)

Фрагмент кода наблюдаемой цепочки с использованием оператора take после оператора switchMap.

Короче говоря, мы получаем несколько выбросов в первом случае и один выброс во втором. Таким образом, чтобы завершить наблюдаемую цепочку после 1 эмиссии, take нужно поместить последним!

Случай 1: мы получаем несколько выбросов - см. Пример https://rxviz.com/v/zopr69mJ
Случай 1: мы получаем несколько выбросов - см. Пример https://rxviz.com/v/zopr69mJ
Случай 2: мы получаем один выпуск и завершим - см. Пример https://rxviz.com/v/B8ZnLPn8
Случай 2: мы получаем один выпуск и завершим - см. Пример https://rxviz.com/v/B8ZnLPn8

Чтобы ответить на вопросы более подробно, давайте рассмотрим Stackblitz (или код ниже, если Stackblitz недоступен для вас).

const src = interval(1000);
src
  .pipe(
    take(1),
    switchMap(() => interval(1000).pipe(take(3)))
  )
  .subscribe(console.log, null, () => console.log('end first'));

src
  .pipe(
    switchMap(() => interval(500)),
    take(1)
  )
  .subscribe(console.log, null, () => console.log('end second'));

// resulting in console logs:

// 0
// end second
// 0
// 1
// 2
// end first

В обоих случаях завершается вызов, поэтому оператор take выполняет свою работу и отписывается

В первом случае (switchMap после take) мы получаем несколько вызовов до того, как завершится обратный вызов, по сравнению с одним вызовом в другом случае.

Для логики отмены подписки посмотрите на источник оператора take здесь. Короче говоря:

if (count <= total) {
  this.destination.next(value);
  if (count === total) {
    this.destination.complete();
    this.unsubscribe();
  }
}

Случай 2: (take после switchMap): логика оператора take заботится о том, чтобы завершить и отписать observable, полученное switchMap после первой отправки события.

Случай 1: (take перед switchMapdestination в приведенном выше фрагменте является вводом для оператора switchMap. Таким образом, take прекращается после первого значения, но наблюдаемое в результате switchMap отправляет событие, и, следовательно, все наблюдаемое продолжается до завершения.

Источник:

#RxJS
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу