Skip to content

Commit

Permalink
💥 NEW: Add auto-retry function for Promise on rejection
Browse files Browse the repository at this point in the history
  • Loading branch information
Shaban-Eissa committed Jun 7, 2024
1 parent ea3613e commit 50fea98
Showing 1 changed file with 81 additions and 0 deletions.
81 changes: 81 additions & 0 deletions 64.auto-retry-Promise-on-rejection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 64. auto-retry Promise on rejection

### Problem

https://bigfrontend.dev/problem/retry-promise-on-rejection

#

### Problem Description

For a web application, fetching API data is a common task.

But the API calls might fail because of Network problems. Usually we could show a screen for Network Error and ask users to retry.

One approach to handle this is **auto retry when network error occurs**.

You are asked to create a `fetchWithAutoRetry(fetcher, count)`, which automatically fetch again when error happens, until the maximum count is met.

For the problem here, there is no need to detect network error, you can just retry on all promise rejections.

#

### Understanding the problem

Write a function that retries fetch upon failure up to N times. The function takes two inputs, a callback function that fetches API data and returns a promise, and an integer representing maximum retry count.

#

### Approach

Fetching data is always asynchronous, so the function needs to return a promise. Within the promise, we can use a `try...catch` block to implement the auto retry. Call the `fetcher` function in the `try` block and then `resolve` the result. If an error is thrown in the `try` block, the statement in the `catch` block will be executed. So in the `catch` block, we can try to fetch the data again if the maximum count is not reached. We can use the variable `maximumRetryCount` to keep track of how many tries we have left. Every time we retry, we decrease the `maximumRetryCount` by 1. If `maximumRetryCount` is equal to 0, the returned promise gets rejected with the thrown error as its value.

### Solution

```js
/**
* @param {() => Promise<any>} fetcher
* @param {number} maximumRetryCount
* @return {Promise<any>}
*/
function fetchWithAutoRetry(fetcher, maximumRetryCount) {
return new Promise((resolve, reject) => {
const retry = async (retriesLeft) => {
try {
const data = await fetcher();
resolve(data);
} catch (err) {
if (retriesLeft === 0) {
reject(err);
return;
}
retry(retriesLeft - 1);
}
};
retry(maximumRetryCount);
});
}
```

#

### Usage
```js
const fetcher = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((data) => resolve(data))
.catch((err) => reject(err));
}, 1000);
});
};

console.log("Start");
fetchWithAutoRetry(fetcher, 5)
.then((data) => console.log(data))
.catch((err) => console.log(err));
console.log("End");

```

0 comments on commit 50fea98

Please sign in to comment.