-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
💥 NEW: Add auto-retry function for Promise on rejection
- Loading branch information
1 parent
ea3613e
commit 50fea98
Showing
1 changed file
with
81 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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"); | ||
|
||
``` |