使用 async-await 实现一个请求失败自动重新请求的函数

在项目开发中, 需要拉取 GA 数据放到自己的数据库中, 用于做更定制化的数据分析和图表等.

但是因为数据较多, GA 一次性只能取得 10w 条数据, 所以需要多次请求才能获取到完整的数据.又因为网络有时波动较大, 在后续的定时任务中可能会出现请求失败的情况.

所以需要一个在请求失败时自动重试的函数.

直接看代码:

// *请求失败时将重新尝试

export async function tryAgain>(
  fn: () => T,
  count: number = 3, // 重试次数
  timeout: number = 5000 // 重试的延迟
): Promise {
  let tryCount = 1;
  let timeId: NodeJS.Timeout;

  const exec = async (): Promise => {
    const res: T | null = await fn().catch((err) => {
      if (tryCount > count) {
        throw err;
      } else {
        console.log(request failed, trying re-request ${tryCount++} \n err:${err});
        // 这里也可以直接返回 err 但是下面的判断条件下需要修改, 比如 if(res instanceof Error)
        return null;
      }
    });
    if (timeId) clearTimeout(timeId);
    if (res) return res;
    else {
      if (timeout) {
      /**
      * 这里的 Promise 只是单纯的等待计时器完成, 不知道这样会不会不好
      * 这里也可以直接把 exec 放到 resolve 里面. 大概是下面这样.
      * 但是会将 Promise 修改为 fulfilled 虽然 exec 报错了将会抛出错误, 也可以正常使用
      * 但是我有点小强迫症, 不喜欢这样.
      * return new Promise((resolve) => {
      *     timeId = setTimeout(() => {
      *         resolve(exec())
      *     }, timeout)
      * })
      */
        await new Promise((resolve) => {
          timeId = setTimeout(() => {
            resolve("timeout");
          }, timeout);
        });
      }
      // *递归 + 尾调用
      return exec();
    }
  };

  return exec();
}

Original: https://www.cnblogs.com/99xx/p/re-request-function.html
Author: 99xx
Title: 使用 async-await 实现一个请求失败自动重新请求的函数

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/644356/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球