3.1 Creación de cadenas de promesas
Cadenas de promesas permiten ejecutar varias operaciones asíncronas en secuencia, pasando el resultado de una operación a la siguiente. Esto hace que el código sea más legible y manejable. Además, las promesas proporcionan poderosas capacidades para el manejo de errores, lo que permite crear aplicaciones confiables y resistentes a fallos.
Concepto principal
Una cadena de promesas se crea al devolver una nueva promesa desde el método then
. Cada método then
devuelve una nueva promesa, lo que permite construir operaciones asíncronas en secuencia.
Ejemplo de una cadena de promesas simple
En este ejemplo, cada método then
realiza su operación y pasa el resultado al siguiente método then
.
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('Step 1 completed');
}, 1000);
});
promise
.then((result) => {
console.log(result); // Mostrará: Step 1 completed
return 'Step 2 completed';
})
.then((result) => {
console.log(result); // Mostrará: Step 2 completed
return 'Step 3 completed';
})
.then((result) => {
console.log(result); // Mostrará: Step 3 completed
})
.catch((error) => {
console.error(error);
});
Ejemplo de cadena con operaciones asíncronas
En este ejemplo, cada método then
espera la finalización de una operación asíncrona antes de ejecutar el siguiente paso:
function asyncOperation(step) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(`${step} completed`);
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result); // Mostrará: Step 1 completed
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result); // Mostrará: Step 2 completed
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Mostrará: Step 3 completed
})
.catch((error) => {
console.error(error);
});
3.2 Manejo de errores en cadenas de promesas
El método catch
se utiliza para manejar errores en una cadena de promesas. Si ocurre un error en cualquiera de las promesas, se pasa al método catch
más cercano. Esto permite manejar errores de manera centralizada, mejorando la legibilidad y el mantenimiento del código.
Ejemplo de manejo de errores
En este ejemplo, el error que ocurre en el Step 2
es capturado por el método catch
, y los métodos then
siguientes no se ejecutan:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true); // Esta operación fallará
})
.then((result) => {
console.log(result); // Este código no se ejecutará
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Este código no se ejecutará
})
.catch((error) => {
console.error('Error:', error); // Mostrará: Error: Step 2 failed
});
Manejo de errores en pasos específicos
A veces es necesario manejar errores en pasos específicos de la cadena sin interrumpir toda la ejecución de la cadena. Para esto se pueden utilizar métodos then
y catch
anidados.
Ejemplo de manejo de errores en pasos específicos
En este ejemplo, el error en Step 2
se maneja de manera local, y la cadena continúa su ejecución con un valor recuperado:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2', true).catch((error) => {
console.warn('Handled error in Step 2:', error);
return 'Recovered from Step 2 error';
});
})
.then((result) => {
console.log(result); // Mostrará: Recovered from Step 2 error
return asyncOperation('Step 3');
})
.then((result) => {
console.log(result); // Mostrará: Step 3 completed
})
.catch((error) => {
console.error('Error:', error); // Este código no se ejecutará
});
3.3 Uso de finally
El método finally
se utiliza para ejecutar código independientemente de si la promesa se completó con éxito o con error. Es útil para realizar acciones finales, como liberar recursos.
Ejemplo de uso de finally:
function asyncOperation(step, shouldFail = false) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldFail) {
reject(`${step} failed`);
} else {
resolve(`${step} completed`);
}
}, 1000);
});
}
asyncOperation('Step 1')
.then((result) => {
console.log(result);
return asyncOperation('Step 2');
})
.then((result) => {
console.log(result);
return asyncOperation('Step 3');
})
.catch((error) => {
console.error('Error:', error);
})
.finally(() => {
console.log('All operations completed'); // Se ejecutará en cualquier caso
});
En este ejemplo, el método finally
se ejecuta en cualquier caso, independientemente de si ocurrió un error o no.
GO TO FULL VERSION