Где разместить RxJs оператор take(1)?
Имеет ли значение, помещаем ли мы take(1)
в начало или конец наблюдаемой цепочки?
Глядя на следующие два (псевдо) примера наблюдаемой цепочки RxJ, имеет ли значение, куда мы помещаем оператор take
?
Пример 1:
.pipe(
take(1),
switchMap(…)
)
Фрагмент кода наблюдаемой цепочки с использованием оператора take перед оператором switchMap
Пример 2:
.pipe(
switchMap(…),
take(1)
)
Фрагмент кода наблюдаемой цепочки с использованием оператора take после оператора switchMap.
Короче говоря, мы получаем несколько выбросов в первом случае и один выброс во втором. Таким образом, чтобы завершить наблюдаемую цепочку после 1 эмиссии, take
нужно поместить последним!
Чтобы ответить на вопросы более подробно, давайте рассмотрим 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
перед switchMap
) destination
в приведенном выше фрагменте является вводом для оператора switchMap
. Таким образом, take
прекращается после первого значения, но наблюдаемое в результате switchMap
отправляет событие, и, следовательно, все наблюдаемое продолжается до завершения.