封装自带取消请求功能的fetch请求

封装自带取消请求功能的 fetch 请求

为了防止我们的同一个请求被多次请求多次,而我们往往只是想要最后一次的结果,这就导致我们前面的请求都是无效请求,所以我们需要一个方法来取消前面的请求,可以参考这篇文档 如何取消我们的请求 ˝

❓:这是我自己尝试的封装,还存在一些问题,下面会说明
💡:

import { rejects } from "assert";
import React from "react";
import { message } from "antd";

type HttpMethod = "GET" | "POST" | "PUT" | "DELETE"; // 可以根据需要扩展
type FetchOptions = RequestInit & { method?: HttpMethod };

/* 自带消除上次的的接口 */
const debouncedFetch = (() => {
  let controller: AbortController | null = null;
  let timeoutId: ReturnType<typeof setTimeout> | null = null;

  return async (
    url: string,
    options: FetchOptions = {},
    delay: number = 300
  ): Promise<Response> => {
    // 如果已经存在一个请求(controller不为空),则取消前一个请求
    if (controller) {
      controller.abort();
    }
    // 清除上一个计时器
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    // 为新请求创建一个新的AbortController
    controller = new AbortController();
    const fetchOptions: FetchOptions = {
      ...options,
      signal: controller.signal,
    }; // 使用新的signal

    // 设置一个计时器
    timeoutId = setTimeout(() => {
      controller = null;
      timeoutId = null;
    }, delay);

    try {
      const response = await fetch(url, fetchOptions);
      if (!response.ok) {
        throw new Error(`HTTP error: ${response.status}`);
      }
      return response; // 返回Response对象,调用者可以根据需要处理(例如调用.text()或.json())
    } catch (err) {
      if (err.name === "AbortError") {
        console.log("请求已被取消");
        return new Promise((_, rejects) => rejects(false));
      } else {
        console.error("Fetch error:", err);
      }
      // throw err;
    }
  };
})();

export default debouncedFetch;

❓: 一般我们请求取消之后,应该只是网络请求(已取消),我们不需要再进行而外的返回和操作
💡:但是我这里写了返回的是一个 reject(false),所以取消之后,我们如果在我们发送请求的地方进行 catch 到我们的结果 false

posted @ 2024-01-19 14:35  郭杰前端开发  阅读(74)  评论(0编辑  收藏  举报
## 希望内容对你有帮助,如果有错误请联系我 q: 1911509826,感谢支持