Una de las preguntas más comunes entre los desarrolladores web que comienzan a usar JavaScript y a consumir APIs es: ¿Qué es una promesa en JavaScript? En este artículo, exploraremos en detalle las promesas, cómo funcionan y cómo puedes utilizarlas para manejar operaciones asíncronas en tu código.
Una promesa (promise
) es un objeto que representa la terminación o el fracaso de una operación que va a tardar un tiempo desconocido en obtener la respuesta de esa operación.
Una promise puede tener estos estados (PromiseState
):
Las promesas nos ayudan a gestionar acciones asíncronas como peticiones a otros sitios fuera de nuestro entorno de ejecución en los cuales desconocemos el tiempo que va a tardar en ejecutarse y devolvernos esa información que hemos solicitado.
Esto las hace diferentes a las variables o a las funciones, ya que una promesa devuelve inmediatamente su respuesta, pero la devuelve como si fuera un “pagaré”, y de hecho te promete que te volverá lo que le has pedido o, fallará. De hecho, si falla, lo normal es rechazar el resultado.
Así que literalmente, una “promesa” nos promete que nos devolverá los datos que hemos solicitado.
Cada vez que esperemos información que no estén directamente bajo nuestro control, deberíamos recibir una promesa. Las promesas van a evitar que la aplicación se bloquee cada vez que tengamos que esperar un resultado que vaya a tardar un tiempo desconocido, la devolución de unos datos pedidos a una API, eventos, acciones de usuario, etc.
Un caso real podrías ser la petición de datos a una API, esta, a su vez depende de un servidor o una base datos y puede tarde un tiempo desconocido en responder, así que sin una promesa, al ejecutarse la petición nuestra aplicación se quedaría esperando la respuesta hasta recibirla el tiempo que fuera (en el mejor de los casos de que la recibamos y no sea esta un error.)
Otro caso podría ser, pedir acceso al usuario desde el navegador a su micrófono o webcam, no tenemos ni idea del tiempo que pueda tardar el usuario o si va a denegar esta petición, pero la página o aplicación debe seguir funcionando.
Una de las maneras más comunes de obtener una promesa es mediante el uso de fetch()
, que se ha convertido en un estándar y está integrado dentro de JavaScript. Pero existen también la librería de axios()
cuyo funcionamiento es similar, pero necesitamos instalar el paquete.
Si ejecutamos estas líneas (mejor si lo hacemos desde un archivo HTML y lo ejecutamos en el navegador):
const apiURL = "https://jsonplaceholder.typicode.com/todos/1";
console.log(fetch(apiURL));
Obtendremos lo siguiente:
Lo que hemos hecho, ha sido pasarle el enlace de una API y hacer fetch
a dicho enlace, y la respuesta ha sido la promesa.
Al hacer fetch
, no sabe cuánto tiempo le costará, entonces con la promise
te avisa y te dice algo así como “voy a buscarlo”, una vez traiga lo prometido, entonces (then
) puedes coger esos datos y hacer lo que quieras con ellos.
Para consumirlas, usaremos .then
, async/await
, pero ¿cómo creamos una promesa?, hay varias maneras:
Crearemos una instancia del objeto Promise
y le pasaremos como callback (resolve, reject) donde:
Promise
que se resuelve con el valor dado: resolve(valor)
. Promise
que se rechaza por el motivo indicado: reject(motivo)
.const miPromesa = new Promise((resolve, reject) => {
const exito = true;
// const existo = false;
if (exito) {
resolve("¡Éxito!");
} else {
reject("Ups.. hubo un error.");
}
});
}
Esto devuelve la promesa, pero además reject y resolve por separado.
Ejemplo:
Puede ser útil si queremospasar los métodos resolve
y reject
a otras partes de tu aplicación en lugar de hacer el trabajo dentro de la propia promesa.
escribendo delante de una función “async
”, esto cambiará la función y pasará de devolver una función convencional a devolver una promesa. Lo bueno de estas es que devolveremos un valor o una promesa, no tenemos que utilizar el método resolve
, simplemente “return
”.
Pruebalo en la consola:
async function fetchData() { return "Datos recibidos"; }
console.log(fetchData())
console.log( await fetchData())
Ahora que ya sabemos qué es una promesa y cómo crearlas, vamos a resolverlas
La función que nos va a devolver una promesa la concatenamos con un .then
, y a este then
le pasamos como callback una función que será la que tenga la respuesta (típicamente se la llama response). Partiendo de uno de los ejemplos anteriores:
const apiURL = "https://jsonplaceholder.typicode.com/todos/1";
const data = fetch(apiURL).then(response => {
return response.json();
});
Console.log(data);
Si la respuesta es rechazada, entonces será un .catch
el que trate la respuesta, donde, el error estará disponible en la función callback.
const apiURL = "https://jsonplaceholder.typicode.com/todos/1";
const data = fetch(apiURL).then(response => {
return response.json();
}) .catch(error => {
console.error('Ha habido un error al recibir la respuesta:', error);
});
Console.log(data);
Se puede añdir un .then
siempre que devuelve una promesa, de manera que se pueden concatenar varios y en el último añadir el catch()
.
Existe también un tercero que no es tan usado: .finally
, el cual se ejecutará tanto si es resuelta como si es rechazada. Así que si nos da por duplicar código dentro del then
y el catch
, como cambiar un estado a false
, o borrar un flag de loading, sin importar el resultado de la promesa, puede escribir eso dentro de .finaly
.
const apiURL = "https://jsonplaceholder.typicode.com/todos/1";
fetch(apiURL)
.then(response => {
console.log(data);
})
.catch(error => {
console.error('Ha habido un error:', error);
})
.finally(() => {
console.log('Esta acción se ejecutara siempre');
// Aquí podrías poner cualquier código que necesites ejecutar independientemente de si hay error o no.
});
Cuando se marca una función con async
, se permite pausar la ejecución de esa función y continuarla una vez que la promesa se haya resuelto. Esto se hace utilizando la palabra clave await
.
const createUser = async () => {
return ‘David’;
}
const user = await createUser();
console.log(user)
La función marcada con async
devuelve una promesa, que await
resuelve.
En mi opinión, esta es una opción que hace el código más comprensible y ordenado. Aunque a veces encadenar múltiples .then()
puede resultar en un código más conciso, la elección entre async/await
y .then()
realmente depende de las preferencias personales y del contexto en el que se esté trabajando.
Uno de los problemas de usar el método then
es que añaden otra capa de complejidad. Si necesitas acceder a los datos fuera de la promesa, debes crear una variable, pasarla y gestionar los valores por defecto antes y después de que la promesa devuelva su resultado.
await, por
otro lado, ofrece una lectura más natural del código, se lee de una manera más intuitiva. Además, podemos esperar el valor, y una vez que lo tengamos, podemos hacer algo con él inmediatamente. No necesitamos preocuparnos tanto por la estructura del código como con then
.
En resumen, entender qué es una promesa en JavaScript y cómo utilizarla es fundamental para manejar operaciones asíncronas de manera efectiva. Con las promesas, puedes asegurarte de que tu código sea más limpio y manejable.
¿Alguna vez te has encontrado con un mensaje que te invita a actuar, ya sea… Leer más
Descubre qué es y para qué sirve la preimpresión digital para conseguir una buena impresión… Leer más
Ampliamos información para las redes sociales. Descubre cómo gestionar correctamente los consentimientos necesarios en las… Leer más
Michael Bierut es mucho más que un diseñador; es un educador ejemplar, un escritor locuaz… Leer más
Hoy os quiero hablar de un tema que me traía de cabeza cuando estaba estudiando… Leer más
Hoy te enseño uno de los plugins de WordPress más populares: Ninja Forms. Durante la lectura… Leer más