From 50fea9875d5a1f2d2f5d74f45ddd2b3cc49cc021 Mon Sep 17 00:00:00 2001 From: Shaban-Eissa Date: Fri, 7 Jun 2024 16:02:01 +0300 Subject: [PATCH] =?UTF-8?q?=F0=9F=92=A5=20NEW:=20Add=20auto-retry=20functi?= =?UTF-8?q?on=20for=20Promise=20on=20rejection?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 64.auto-retry-Promise-on-rejection.md | 81 +++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 64.auto-retry-Promise-on-rejection.md diff --git a/64.auto-retry-Promise-on-rejection.md b/64.auto-retry-Promise-on-rejection.md new file mode 100644 index 0000000..7ed8f04 --- /dev/null +++ b/64.auto-retry-Promise-on-rejection.md @@ -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} fetcher + * @param {number} maximumRetryCount + * @return {Promise} + */ +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"); + +```