react hook 接口轮询

复制代码
// 轮询接口

import { useCallback, useRef, useEffect } from "react";
const sleep = (time) => {
  return new Promise((resolve) => setTimeout(resolve, time));
};
const useUnMount = (fn) => {
  useEffect(
    () => () => {
      fn();
    },
    [fn]
  );
};

const usePolling = (polling) => {
  const isPollingRef = useRef(false);
  const cancelRef = useRef(false);

  const doPolling = useCallback(() => {
    // 是否正在轮询,是,返回,不能多个接口同时轮询,避免这些接口有先后顺序相互影响
    if (isPollingRef.current) {
      return;
    }
    isPollingRef.current = true;

    const pollNext = async () => {
      // 如果掉了取消轮询,那么就返回不执行
      if (cancelRef.current) {
        isPollingRef.current = false;
        cancelRef.current = false;
        return;
      }
      // 发送请求,返回值组装一下,给个 hasFinshed 判断是否还要继续轮询
      const { hasFinshed } = await polling();

      if (!hasFinshed) {
        await sleep(3000);
        pollNext();
      } else {
        isPollingRef.current = false;
      }
    };

    pollNext();
  }, [polling]);

  const cancelPolling = useCallback(() => {
    if (isPollingRef.current) {
      cancelRef.current = true;
    }
  }, []);

  useUnMount(cancelPolling);

  return [doPolling, cancelPolling];
};

export default usePolling;
复制代码

调用示例

复制代码
import usePolling from "@/plugins/usePolling"; 

 /* ========== 导入轮询 ========== */
  const submitPublicBagPolling = useCallback(async () => {
    let resPolling = await axios
      .post("/progress", {
        id: id,
      })
      .catch(() => {
        setLoading(false);
      });
    if (!resPolling) {
      setLoading(false);
      return { hasFinshed: true };
    }
    if (resPolling.data?.finish) {
      message.success(``);
      setLoading(false);
    }
    return { hasFinshed: resPolling.data?.finish };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id]);
  const [doPollingType, cancelPollingType] = usePolling(submitPublicBagPolling); //接口轮询hook
  /* ========== 导入 ========== */
  const submitPublicBag = async (values) => {
    if (Object.keys(values).length == 0) {
      setPublicBagVis(false);
      return;
    }
    setLoading(true);
    let res = await axios.post("/batchsms/contact/crowdpack/submit", {
      ...values,
        id: id,
    });
    if (!res) {
      setLoading(false);
      return false;
    }
    if (res.data?.finish) {
      message.success(``);
      setLoading(false);
    } else {
      doPollingType();
    }
  };
复制代码

 

参考:https://juejin.cn/post/7085174569484582925

posted @   Janni  阅读(2127)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2021-06-02 兼容性测试工具
点击右上角即可分享
微信分享提示

目录导航