# Conversión a Promesas

La similitud entre Observables y Promesas radica en que ambas colecciones pueden producir valores a lo largo del tiempo, pero la diferencia es que los Observables pueden producir ningún, o más de un valor, mientras que las Promesas producen un único valor cuando se resuelven con éxito.

## Problemas

Por esta razón, en RxJS 7, el tipo de retorno del método `toPromise()` se ha modificado para reflejar mejor el hecho de que los Observables pueden producir cero valores. Esto puede suponer un *breaking change* para algunos proyectos, ya que el tipo de retorno se ha cambiado de `Promise<T>` a `Promise<T | undefined>`.

Además, el nombre del método `toPromise()` nunca indicaba cuál de los valores emitidos por el Observable sería el que tomaría la Promesa al resolverse, ya que los Observables pueden emitir múltiples valores a lo largo del tiempo. Al convertir a una Promesa, quizá se quiera elegir qué valor elegir - si el primer valor que haya llegado, o el último. Para solucionar estos problemas, se decidió que el método `toPromise` pasaría a estar obsoleto, y se introducieron dos nuevas funciones *helper* para la conversión a Promesas.

Also, `toPromise()` method name was never indicating what emitted value a Promise will resolve with because Observables can produce multiple values over time. When converting to a Promise, you might want to choose which value to pick - either the first value that has arrived or the last one. To fix all these issues, we decided to deprecate toPromise(), and to introduce the two new helper functions for conversion to Promises.

## Las dos nuevas funciones

Para reemplazar el método `toPromise()` obsoleto, se debe utilizar una de las dos funciones estáticas de conversión `firstValueFrom` or `lastValueFrom`.

### lastValueFrom

`lastValueFrom` es prácticamente igual que `toPromise()`. Esto quiere decir que se resolverá con el último valor que haya llegado cuando el Observable se complete, pero con una diferencia en su comportamiento cuando el Observable se complete sin emitir ningún valor. En este caso, `toPromise()` se resolvía con éxito con `undefined` , mientras que `lastValueFrom` se rechazará con `EmptyError`. De esta menera, el tipo de retorno de `lastValueFrom` es `Promise<T>`, al igual que `toPromise()` en RxJS 6.

#### Ejemplo

```
    import { interval, take, lastValueFrom } from 'rxjs';

    async function execute() {
      const source$ = interval(2000).pipe(take(10));
      const finalNumber = await lastValueFrom(source$);
      console.log(`El último número es ${finalNumber}`);
    }

    execute();

    // Salida esperada:
    // "El último número es 9"
```

### firstValueFrom

Sin embargo, quizá se quiera obtener el primer valor que llegue sin esperar a que el Observable se complete. En este caso se puede utilizar `firstValueFrom`. `firstValueFrom` se resolverá a una Promesa con el primer valor que haya emitido el Observable, y cancelará la suscripción automáticamente para retener recursos. `firstValueFrom` también se rechazará con un EmptyError si el Observable se completa sin emitir ningún valor.

#### Ejemplo

```
    import { interval, firstValueFrom } from 'rxjs';

    async function execute() {
      const source$ = interval(2000);
      const firstNumber = await firstValueFrom(source$);
      console.log(`El primer número es ${firstNumber}`);
    }

    execute();

    // Salida esperada:
    // "El primer número es 0"
```

Ambas funciones devolverán una Promesa que se rechazará si se produce un error en el Observable fuente. La promesa se rechazará con el mismo error que haya ocurrido en el Observable.

### Uso del valor por defecto

Si no se desea que las Promesas creadas por `lastValueFrom` o `firstValueFrom` se rechacen con EmptyError en el caso de que no se emita ningún valor antes de que el Observable se complete, se puede utilizar el segundo parámetro. Este segundo parámetro dbe ser un objeto con un parámetro `defaultValue`. El valor en `defaultValue` se utilizará para resolver la Promesa si el Observable fuente se completa sin emitir ningún valor.

```
import { firstValueFrom, EMPTY } from 'rxjs';

const result = await firstValueFrom(EMPTY, { defaultValue: 0 });
console.log(result);

// Salida esperada:
// 0
```

## Advertencia

Solo se debe utilizar la función `lastValueFrom` si se tiene la certeza de que el Observable fuente se acabará completando. La función `firstValueFrom` se debe utilizar si se tiene la certeza de que el Observable fuente emitirá al menos un valor, o se acabará completando. Si el Observable fuente no se completa, ni emite ningún valor, se puede obtener una Promesa que esté colgada, y potencialmente todo el estado de una función asíncrona acabaría colgando en memoria. Para evitar esta situación, se puede utilizar timeout, take, takeWhile, o takeUntil, entre otros.


---

# 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/guias/breaking-changes/conversion-to-promises.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.
