redux RTK查询:maxRetries && backoff

igsr9ssn  于 2023-08-05  发布在  其他
关注(0)|答案(1)|浏览(76)

我正在使用RTK查询来执行API调用。我有一个突变,如果得到错误响应,我想重试获取。我还想控制重试之间的延迟。

**注意:我尝试了maxRetries,但我无法控制重试之间的延迟
**注2:深入挖掘后,我在“extraOptions”下找到了“retryCondition”fn。我还检查了“后退”。但是我不确定如何将这些结合起来来控制延迟。我在互联网上搜索&&没有找到任何关于回退的信息,文档中也简要地提到了“重试”。

ltqd579y

ltqd579y1#

你是对的,文档没有很好地展示这个功能,我不得不在仓库中寻找信息。retry函数有两个参数,第一个是基本查询函数,第二个是默认选项(RetryOptions)配置对象。
参见RetryOptions类型声明:

export type RetryOptions = {
  /**
   * Function used to determine delay between retries
   */
  backoff?: (attempt: number, maxRetries: number) => Promise<void>
} & (
  | {
      /**
       * How many times the query will be retried (default: 5)
       */
      maxRetries?: number
      retryCondition?: undefined
    }
  | {
      /**
       * Callback to determine if a retry should be attempted.
       * Return `true` for another retry and `false` to quit trying prematurely.
       */
      retryCondition?: RetryConditionFunction
      maxRetries?: undefined
    }
)

字符串
backoff属性是您感兴趣的

(attempt: number, maxRetries: number) => Promise<void>


它是一个接受attempt和max重试参数并返回Promise的函数。幸运的是,已经有一个默认的回退函数可以参考:

/**
 * Exponential backoff based on the attempt number.
 *
 * @remarks
 * 1. 600ms * random(0.4, 1.4)
 * 2. 1200ms * random(0.4, 1.4)
 * 3. 2400ms * random(0.4, 1.4)
 * 4. 4800ms * random(0.4, 1.4)
 * 5. 9600ms * random(0.4, 1.4)
 *
 * @param attempt - Current attempt
 * @param maxRetries - Maximum number of retries
 */
async function defaultBackoff(attempt: number = 0, maxRetries: number = 5) {
  const attempts = Math.min(attempt, maxRetries)

  const timeout = ~~((Math.random() + 0.4) * (300 << attempts)) // Force a positive int in the case we make this an option
  await new Promise((resolve) =>
    setTimeout((res: any) => resolve(res), timeout)
  )
}


在我看来,这是一个非常好的默认函数,但如果需要的话,您可以构建自己的函数。
示例:
1秒、2秒、3秒、...maxRetries秒

const customBackOff = async (attempt = 0, maxRetries = 5) => {
  const attempts = Math.min(attempt, maxRetries);

  await new Promise(resolve => {
    setTimeout(resolve, attempts * 1000);
  });
};


每次重试1秒

const customBackOff = async (attempt = 0, maxRetries = 5) => {
  await new Promise(resolve => {
    setTimeout(resolve, 1000);
  });
};


在数组中查找。

const backoffDelays = [500, 2000, 5000];

const customBackOff = async (attempt = 0, maxRetries = 5) => {
  const attempts = Math.min(backoffDelays.length - 1, maxRetries);

  await new Promise(resolve => {
    setTimeout(resolve, backoffDelays[attempts]);
  });
};


按照文档中的示例来修饰基本查询函数。

const customBaseQuery = retry(
  fetchBaseQuery({ baseUrl: '/' }),
  { backoff: customBackOff, maxRetries: 5 }
);

export const api = createApi({
  baseQuery: customBaseQuery,
  endpoints: (build) => ({
    ....
  }),
});

相关问题