Home > Blockchain >  Retry functionality in promise chain
Retry functionality in promise chain

Time:11-22

i have a promise chain

If i receive error in getServiceCost I want to repeat the chain again (retry) for 2 times how can i achieve this when using Promise chain , meaning again execute 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);
    });
}

If i receive error in getServiceCost I want to repeat the chain again (retry) for 2 times how can i achieve this when using Promise chain , meaning again execute getUser, getServiceCost

CodePudding user response:

I'd use an async function (all modern environments support them, and you can transpile for obsolete environments), which lets you use a simple loop. Perhaps as a utility function you can reuse:

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
}

Using it:

callWithRetry(() => getUser(100).then(getServices).then(getServiceCost))
.then(console.log)
.catch(error => { /*...handle/report error...*/ });

Or

callWithRetry(async () => {
    const user = await getUser(100);
    const services = await getServices(user);
    return await getServiceCost(services);
})
.then(console.log)
.catch(error => { /*...handle/report error...*/ });
  • Related