接口异常重新执行实现方案

在开发中,很多小伙伴可能会遇到不少的情况,那就是请求服务器的时候,因为网络问题或者其他别的导致请求失败,如何处理。

  • 举一个最简单的业务场景就是:当项目中部署了性能监控,当监控的请求数量达到自定义的阈值时,要求发送数据给后端,如果此时存在发送失败,如何实现重发?

实现方案

  1. 借用第三方库实现
  2. 自定义retry

1.借用第三方库实现

1. 使用 retry 库

安装 npm install retry || yarn add retry
使用:

import retry from 'retry';

export async function getServerSideProps() {
  const operation = retry.operation({
    retries: 3, // 重试次数
    factor: 2,  // 指数退避的增长因子
    minTimeout: 1000, // 初始等待时间
    maxTimeout: 5000, // 最大等待时间
  });

  return new Promise((resolve, reject) => {
    operation.attempt(async (currentAttempt) => {
      try {
        const res = await fetch('https://api.example.com/');
        if (res.code === 失败) throw new Error('请求失败');
        resolve({ data: { res } });
      } catch (error) {
        if (operation.retry(error)) {
          console.log(`Attempt ${currentAttempt} failed. Retrying...`);
          return;
        }
        reject(error); // 超过重试次数后抛出错误
      }
    });
  });
}

function Page({ data }) {
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.content}</p>
    </div>
  );
}

export default Page;

2. 使用 axios-retry库

如果使用使用 axios 进行 HTTP 请求,可以使用 axios-retry 库来实现重试逻辑。

安装:npm install axios axios-retry || yarn add axios axios-retry
使用案例 1.配置 Axios 实例

import axios from 'axios';
import { retry } from 'axios-retry';

// 创建 Axios 实例
const instance = axios.create({
  baseURL: 'https://api.example.com',
  timeout: 5000,
});

// 使用 axios-retry 配置重试策略
retry(instance, {
  retries: 3, // 尝试重试的最大次数
  retryDelay: (retryCount) => {
    // 根据重试次数计算延迟时间
    return retryCount * 1000; // 比如第一次重试等待1秒,第二次2秒...
  },
  shouldResetTimeout: true, // 每次重试是否重新设置超时时间
  retryCondition: (error) => {
    // 自定义条件判断是否应该重试
    const { response, config } = error;
    // 如果服务器返回 404,则不再重试
    if (response && response.status === 404) return false;
    // 其他情况默认重试
    return true;
  }
});

export default instance;

2. 使用 Axios 实例发起请求

import api from './api'; // 引入上面配置的 Axios 实例

api.get('/some-endpoint')
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error('请求失败:', error);
  });

以上就是axios-retry 简单案例,可以根据自己的业务需求进行配置

2.自定义retry

async function fetchWithRetry(url, options = {}, retries = 3, delay = 1000) {
  try {
    const res = await fetch(url, options);
    if (!res.ok) throw new Error('请求失败');
    return res;
  } catch (error) {
    if (retries > 0) {
      console.log(`剩余发送次数${retries}`);
      await new Promise((resolve) => setTimeout(resolve, delay));
      return fetchWithRetry(url, options, retries - 1, delay * 2); // 指数退避
    } else {
      throw error; // 超过重试次数后抛出错误
    }
  }
}

export async function getServerSideProps() {
  try {
    const data = await fetchWithRetry('https://api.example.com/');
    return { props: { data } };
  } catch (error) {
    return {
      props: {
        error: 'Failed to fetch data',
      },
    };
  }
}

function Page({ data, error }) {
  if (error) {
    return <div>Error: {error}</div>;
  }
  return (
    <div>
      <h1>{data.title}</h1>
      <p>{data.content}</p>
    </div>
  );
}

export default Page;
  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值