Sunny-117 / js-challenges

✨✨✨ Challenge your JavaScript programming limits step by step

Home Page:https://juejin.cn/column/7244788137410560055

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Promise.retry 超时重新请求,并在重试一定次数依然失败时输出缓存内容

Sunny-117 opened this issue · comments

commented
Promise.retry = (callback, retryTime) => {
  // const curPromise = callback()
  return new Promise((resolve, reject) => {
    callback().then((value) => {
      resolve(value)
    }, (reason) => {
      if (!retryTime) reject(reason)
      else{
        Promise.retry(callback, --retryTime).then(resolve, reject)
      }
    })
  })
}
//let count = 0
// Promise.retry(() => {
//   console.log(++count)
//   return count === 3 ? Promise.resolve('success') : Promise.reject('failed')
// }, 3).then((value) => console.log(value), console.log)
/**
 * 超时重新请求,并在重试一定次数依然失败时输出缓存内容
 * @param {*} promiseFactory 一个返回 Promise 的函数,表示要执行的异步操作。
 * @param {*} maxRetries 一个整数,表示最大的重试次数。
 * @param {*} timeout 一个整数,表示每次重试的间隔时间(单位为毫秒)。
 * @param {*} cache 一个可选的参数,表示缓存的内容,如果重试多次依然失败,则会返回该缓存内容。
 * @returns promise
 */
function retry(promiseFactory, maxRetries, timeout, cache=null) {
  return new Promise((resolve, reject) => {
    let retries = 0;
    const executePromise = () => {
      promiseFactory()
        .then(resolve)
        .catch((error) => {
          retries++;
          if (retries >= maxRetries) {
            if (cache) {
              resolve(cache);
            } else {
              reject(error);
            }
          } else {
            setTimeout(executePromise, timeout);
          }
        });
    };
    executePromise();
  });
}
// ----------test----------
!(() => {
  const fetchData = () => {
    // 返回一个 Promise 对象,表示异步请求数据
    return fetch('http://example.com/data')
      .then((response) => response.json())
      .then((data) => {
        // 处理数据
        return data;
      });
  };

  retry(fetchData, 3, 10000, '缓存内容')
    .then((data) => {
      // 成功获取数据
      console.log(data);
    })
    .catch((error) => {
      // 请求失败或超时,并且重试多次依然失败
      console.error(error);
    });
})()
commented

// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function (promiseFunc, num = 2) {
return promiseFunc().then(null, (e) => {
if (num > 0) {
num -= 1
console.log('重试')
return Promise.retry(promiseFunc, num)
}
return Promise.reject(e)
})
}
// test
function getProm() {
const n = Math.random()
return new Promise((resolve, reject) => {
setTimeout(() => (n > 0.9 ? resolve(n) : reject(n)), 1000)
})
}

Promise.retry(getProm)
.then((res) => {
console.log('成功', res)
})
.catch((err) => {
console.log('请求失败:', err)
})

commented

// 实现 Promise.retry,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正的 reject
Promise.retry = function (promiseFunc, num = 1) {
return promiseFunc().then(undefined, (err) => {
if (num > 0) {
num--;
return Promise.retry(promiseFunc, num);
}
return Promise.reject(err);
});
};
// test
function getProm() {
const n = Math.random();
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log("开炮");
n > 0.9 ? resolve(n) : reject(n);
}, 1000);
});
}

        Promise.retry(getProm)
            .then((res) => {
                console.log("成功", res);
            })
            .catch((err) => {
                console.log("请求失败:", err);
            });
Promise.retry = function(promiseCreator, limitTime, limitCount, cache) {
  return new Promise((resolve, reject) => {
    let retryCount = 1;
    
    const fn = () => {
      Promise.race([promiseCreator(), new Promise((innerResolve, innerReject) => {
        setTimeout(() => {
          innerReject('timeout');
        }, limitTime);
      })]).then((value) => {
        resolve(value)
      }, error => {
        console.log('开始尝试', retryCount)
        retryCount++;
        if (retryCount > limitCount) {
          if (cache) {
            resolve(cache);
          } else {
            reject(error)
          }
          return;
        }
        fn();
      })
    }

    fn();
  })
}
commented
Promise.retry = function (promiseFunc, num = 1) {
  return promiseFunc().then((res) => {
    return res
  }, (err) => {
    if (num > 0) {
      num--;
      return Promise.retry(promiseFunc, num);
    }
    return Promise.reject(err);
  });
};

function getProm() {
  const n = Math.random();
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(n)
      console.log("开炮");
      n > 0.9 ? resolve(n) : reject(n);
    }, 1000);
  });
}

Promise.retry(getProm)
  .then((res) => {
    console.log("成功", res);
  })
  .catch((err) => {
    console.log("请求失败:", err);
  });
/**
 * Promise.retry当请求失败的时候,重新发起请求,直到请求成功
 * @param fn
 * @param time 重新请求的次数
 * @param delay 重启的延迟时间
 * @returns {Promise<unknown>}
 * @private
 */
Promise._retry = function (fn, time, delay) {
  let count = 0
  return new Promise((resolve, reject) => {
    function retry () {
      fn().then(res => {
        resolve(res)
      }, error => {
        count++
        if (count < time) {
          setTimeout(() => {
            console.log(`第${count}/${time}次请求`)
            // 如果失败,就重新请求
            retry()
          }, delay)
        } else {
          reject(new Error(`请求失败,以尝试${count}次`))
        }
      })
    }
    
    retry()
  })
}


// 示例:模拟一个可能失败的异步操作
const asyncOperation = () => {
  const random = Math.random();
  if (random < 0.3) {
    return Promise.resolve('Operation succeeded');
  } else {
    return Promise.reject(new Error('Operation failed'));
  }
};

// 使用 retryPromise 函数
Promise._retry(asyncOperation, 3, 2000)
.then((result) => {
  console.log(result);
})
.catch((error) => {
  console.error(error.message);
});