# refCount

💡 Utilizar el operador [share](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/share/README.md) es equivalente a utilizar el operador [publish](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publish/README.md) (convirtiendo el Observable en uno caliente) junto al operador refCount.

<details>

<summary>Signatura</summary>

#### Firma

`refCount<T>(): MonoTypeOperatorFunction<T>`

#### Parámetros

No recibe ningún parámetro.

### Retorna

`MonoTypeOperatorFunction<T>`

</details>

## Descripción

Al utilizar alguna de las variantes del operador [publish](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/publish/README.md), o el operador [multicast](https://github.com/puntotech/rxjs-docu/blob/master/operators/multicasting/multicast/README.md), era necesario llamar manualmente al método connect() para suscribirse a la fuente y, posteriormente, gestionar la cancelación de la suscripción para evitar posibles pérdidas de memoria.

Para que automatizar el proceso y evitar errores, se creó el operador refCount, que hace ambas cosas automáticamente.

![Diagrama de canicas del operador refCount](https://github.com/puntotech/rxjs-docu/blob/master/assets/images/marble-diagrams/multicasting/refCount.png)

Internamente, cuenta las suscripciones al Observable y se suscribe (una sola vez) a la fuente si el número de suscripciones es mayor que 0. Si el número de suscripciones es menor que 1, se cancela la suscripción a la fuente. De esta manera se puede garantizar que cualquier operador anterior a `refCount` se ejecuta una única vez por cada evento, independientemente del número de suscripciones al Observable objetivo.

## Ejemplos

**Compartir el Observable fuente de forma automática con multicast + refCount**

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-refcount-multicast?file=index.ts)

```javascript
import { interval, Subject, timer } from "rxjs";
import { take, takeUntil, tap, multicast, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

// En lugar de cancelar la suscripción manualmente, se va a utilizar la técnica takeUntil + Subject
const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  multicast(() => new Subject()),
  // Al usar refCount, ya no es necesario llamar a connect() manualmente
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
// refCount === 2
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

// refCount === 0, se cancela la suscripción a number$
timer(2000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  Observador 2: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  Observador 2: 1,
  (1s) 
  Fin
 */
```

**Compartir el Observable fuente de forma automática con publish + refCount**

💡 El operador publish es equivalente a `multicast(() => new Subject())`

[StackBlitz](/operadores/multicasting/refcount.md)

```javascript
import { interval, Subject, timer } from "rxjs";
import { take, takeUntil, tap, multicast, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

// En lugar de cancelar la suscripción manualmente, se va a utilizar la técnica takeUntil + Subject
const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  multicast(() => new Subject()),
  // Al usar refCount, ya no es necesario llamar a connect() manualmente
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));
// refCount === 2
multicasted$.subscribe((val) => console.log(`Observador 2: ${val}`));

// refCount === 0, se cancela la suscripción a number$
timer(2000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  Observador 2: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  Observador 2: 1,
  (1s) 
  Fin
 */
```

**Compartir el Observable fuente de forma automática con publishReplay + refCount**

💡 El operador publish es equivalente a `multicast(() => new ReplaySubject())`.

Para que los observadores que se suscriban tarde puedan recibir los valores que se hayan emitido anterioremente, se puede utilizar publishReplay:

[StackBlitz](https://stackblitz.com/edit/docu-rxjs-refcount-publishreplay?file=index.ts)

```javascript
import { interval, Subject, timer } from "rxjs";
import { publishReplay, take, takeUntil, tap, refCount } from "rxjs/operators";

const number$ = interval(1000).pipe(take(10));

const stop$ = new Subject();

const multicasted$ = number$.pipe(
  tap(() =>
    console.log("Fuente compartida, efecto secundario se ejecuta una sola vez")
  ),
  publishReplay(),
  refCount(),
  takeUntil(stop$)
);

// refCount === 1, se hace la suscripción a number$
multicasted$.subscribe((val) => console.log(`Observador 1: ${val}`));

// refCount === 2
timer(3000)
  .pipe(
    tap(() =>
      multicasted$.subscribe((val) => console.log(`Observador tardío: ${val}`))
    )
  )
  .subscribe();

// refCount === 0, se cancela la suscripción a number$
timer(4000)
  .pipe(
    tap(() => stop$.next()),
    tap(() => console.log("Fin"))
  )
  .subscribe();

/* Salida:
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 0,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 1,
  (1s) 
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 2,
  Observador tardío: 0,
  Observador tardío: 1,
  Observador tardío: 2,
  (1s)
  Fuente compartida, efecto secundario se ejecuta una sola vez,
  Observador 1: 3,
  Observador tardío: 3,
  Fin
*/
```

### Ejemplo de la documentación oficial

En el siguiente ejemplo hay dos Observables intervalo transformados en Observables conectables mediante el operador `publish`. El primero utiliza el operador `refCount`, mientras que el segundo no. Se debe tener en cuenta que un Observable conectable no hace nada hasta que no se haga una llamada a su función `connect`.

```javascript
import { interval } from "rxjs";
import { tap, publish, refCount } from "rxjs/operators";

// Transformar el Observable interval en un ConnectableObservable (caliente)
const refCountInterval = interval(400).pipe(
  tap((num) => console.log(`refCount ${num}`)),
  publish(),
  refCount()
);

const publishedInterval = interval(400).pipe(
  tap((num) => console.log(`publish ${num}`)),
  publish()
);

refCountInterval.subscribe();
refCountInterval.subscribe();
/* 'refCount 0' -----> 'refCount 1' -----> etc.
 Todas las subscripciones recibirán el mismo valor y tanto tap como cualquier otro operador
 que esté antes del operador publish se ejecutará una vez por cada evento, independientemente del número de suscripciones
*/

publishedInterval.subscribe();
// No ocurre nada hasta que no se llame a la función connect() del Observable
```

### Recursos adicionales

[![Source code](https://github.com/puntotech/rxjs-docu/blob/master/doc/operators/multicasting/assets/icons/source-code.png)](https://github.com/ReactiveX/rxjs/blob/master/src/internal/operators/refCount.ts)

[Documentación oficial en inglés](https://rxjs.dev/api/operators/refCount)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.rxjs.es/operadores/multicasting/refcount.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
