Позиция оператора share
в конвейере важна, поскольку она определяет, сколько подписчиков подпишутся на операторы, предшествующие share
.
Рассмотрим следующий пример:
const interval$ = interval(1000).pipe(
tap(() => console.log("Interval Triggered")
);
interval$.subscribe();
interval$.subscribe();
Вы увидите, что мы получаем два консольных сообщения каждую секунду. Это имеет смысл, потому что в Rx JS каждый подписчик («потребитель») заставит фабрику создать нового «производителя» (здесь setInterval
). В этом случае - нет оператора share
- каждый абонент будет go вверх по цепочке операторов и подпишется на предыдущего оператора - пока мы не подпишемся на interval
дважды.
Теперь давайте посмотрим at share
:
const interval$ = interval(1000).pipe(
tap(() => console.log("Interval Triggered"),
share()
);
interval$.subscribe();
interval$.subscribe();
В этой версии мы будем получать только одно сообщение в секунду. Почему?
Потому что share
не будет подписываться на его источник, пока есть один активный подписчик. Итак, мы подписываемся на share()
дважды, а share()
только на interval
один раз.
Если мы поменяем позиции, то получим другой результат:
const interval$ = interval(1000).pipe(
share(),
tap(() => console.log("Interval Triggered"),
);
interval$.subscribe();
interval$.subscribe();
В этом В этом случае мы дважды подписываемся на tap
, а эти два оператора tap
дважды подписываются на share
. Вот почему мы получаем два консольных сообщения в секунду.
Как показывает опыт, вы, скорее всего, захотите, чтобы ваш share
был в конце вашего канала, так как это вызовет операторы, которые идут перед share
подписаться только один раз.
Чтобы объяснить потребление ресурсов ЦП: я подозреваю, что вы очень часто подписываетесь на этот Observable - поскольку share
не является последним оператором, это означает, что вы повторно подпишетесь на flatMap
et c. снова и снова.