In many real-world scenarios, especially when making network requests, temporary failures are common. A common interview question is to implement a Retry function for promise up to N times before rejecting it.
In this article, weβll break down how to implement this function step by step.
π§βπ» Problem Statement
Implement a retryPromise
function that accepts a promise-returning function and retries it up to n
times if it fails. If all attempts fail, it should reject with the last error.
const unreliableNetworkCall = () => {
return new Promise((resolve, reject) => {
if (Math.random() > 0.7) resolve("Success!");
else reject("Failed!");
});
};
retryPromise(unreliableNetworkCall, 3)
.then(result => console.log(result))
.catch(error => console.error(error));
In this example, retryPromise
will try calling unreliableNetworkCall
up to 3 times before rejecting the promise.
π‘ Plan & Approach for Retry Function
Weβll implement the retryPromise
function with the following steps:
- Accept a promise-returning function and retry count.
- Use a recursive or loop-based approach to retry the promise.
- Resolve if successful; reject after N failures.
π οΈ Solution: Recursive Approach
Hereβs a recursive implementation of retryPromise
.
function retryPromise(fn, retries) {
return new Promise((resolve, reject) => {
function attempt(remainingRetries) {
fn()
.then(resolve)
.catch((error) => {
if (remainingRetries === 0) {
reject(error);
} else {
console.log(`Retrying... Attempts left: ${remainingRetries}`);
attempt(remainingRetries - 1);
}
});
}
attempt(retries);
});
}
π Explanation:
retryPromise(fn, retries)
: Takes a promise-returning functionfn
and the number of retries.- Recursive function
attempt(remainingRetries)
:- Calls the function
fn
. - If it succeeds (
.then
), resolve the promise. - If it fails (
.catch
), retry untilremainingRetries
reaches 0.
- Calls the function
- Logs each retry and rejects with the last error if all retries fail.
π οΈ Solution: Iterative Approach
A loop-based solution can be more intuitive for some developers.
async function retryPromise(fn, retries) {
let lastError;
for (let i = 0; i <= retries; i++) {
try {
return await fn();
} catch (error) {
lastError = error;
console.log(`Retry ${i + 1} failed.`);
}
}
throw lastError;
}
π Explanation:
for
loop retries the promise up toretries
times.- If
fn
succeeds, it returns the result. - If all attempts fail, it throws the last encountered error.
β Use Cases & Best Practices
- Network Requests: Retry failed HTTP requests due to temporary issues (e.g., server overload, network glitch).
- Exponential Backoff: Add delay between retries to avoid overloading the system.
- Configurable Retry Logic: Customize the number of retries, delays, and error-handling behaviour.
This question was asked in Zepto interview for the SDE2 Frontend role, and the question was shared on the LinkedIn Platform.