tengo una cadena de promesas
Si recibo un error en getServiceCost, quiero repetir la cadena nuevamente (reintentar) 2 veces, ¿cómo puedo lograr esto cuando uso Promise chain, lo que significa ejecutar nuevamente getUser, getServiceCost?
getUser(100) .then(getServices) .then(getServiceCost) .then(console.log); function getUser(userId) { return new Promise((resolve, reject) => { console.log('Get the user from the database.'); setTimeout(() => { resolve({ userId: userId, username: 'admin' }); }, 1000); }) } function getServices(user) { return new Promise((resolve, reject) => { console.log(`Get the services of ${user.username} from the API.`); setTimeout(() => { resolve(['Email', 'VPN', 'CDN']); }, 3 * 1000); }); } function getServiceCost(services) { return new Promise((resolve, reject) => { console.log(`Calculate the service cost of ${services}.`); setTimeout(() => { resolve(services.length * 100); }, 2 * 1000); }); }Si recibo un error en getServiceCost, quiero repetir la cadena nuevamente (reintentar) 2 veces, ¿cómo puedo lograr esto cuando uso Promise chain, lo que significa ejecutar nuevamente getUser, getServiceCost?
Usaría una función async (todos los entornos modernos las admiten y puede transpilar para entornos obsoletos), que le permite usar un bucle simple. Quizás como una función de utilidad puedes reutilizar:
async function callWithRetry(fn, retries = 3) { while (retries-- > 0) { try { return await fn(); } catch (error) { if (retries === 0) { throw error; } } } return new Error(`Out of retries`); // Probably using an `Error` subclass }Usándolo:
callWithRetry(() => getUser(100).then(getServices).then(getServiceCost)) .then(console.log) .catch(error => { /*...handle/report error...*/ });O
callWithRetry(async () => { const user = await getUser(100); const services = await getServices(user); return await getServiceCost(services); }) .then(console.log) .catch(error => { /*...handle/report error...*/ });