老妞 發表於 2022-6-2 10:59:00

react hook 接口轮询

<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 轮询接口</span>
<span style="color: rgba(0, 0, 0, 1)">
import { useCallback, useRef, useEffect } from </span>"react"<span style="color: rgba(0, 0, 0, 1)">;
const sleep </span>= (time) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
</span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">new</span> Promise((resolve) =&gt;<span style="color: rgba(0, 0, 0, 1)"> setTimeout(resolve, time));
};
const useUnMount </span>= (fn) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
useEffect(
    () </span>=&gt; () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      fn();
    },
   
);
};

const usePolling </span>= (polling) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
const isPollingRef </span>= useRef(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
const cancelRef </span>= useRef(<span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);

const doPolling </span>= useCallback(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 是否正在轮询,是,返回,不能多个接口同时轮询,避免这些接口有先后顺序相互影响</span>
    <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isPollingRef.current) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    isPollingRef.current </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;

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

      </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">hasFinshed) {
      await sleep(</span>3000<span style="color: rgba(0, 0, 0, 1)">);
      pollNext();
      } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      isPollingRef.current </span>= <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
      }
    };

    pollNext();
}, );

const cancelPolling </span>= useCallback(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (isPollingRef.current) {
      cancelRef.current </span>= <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">;
    }
}, []);

useUnMount(cancelPolling);

</span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> ;
};

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> usePolling;</pre>
</div>
<h2>调用示例</h2>
<div class="cnblogs_code">
<pre>import usePolling from "@/plugins/usePolling"<span style="color: rgba(0, 0, 0, 1)">;

</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> ========== 导入轮询 ========== </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
const submitPublicBagPolling </span>= useCallback(async () =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    let resPolling </span>=<span style="color: rgba(0, 0, 0, 1)"> await axios
      .post(</span>"/progress"<span style="color: rgba(0, 0, 0, 1)">, {
      id: id,
      })
      .</span><span style="color: rgba(0, 0, 255, 1)">catch</span>(() =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
      setLoading(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      });
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">resPolling) {
      setLoading(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> { hasFinshed: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)"> };
    }
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (resPolling.data?<span style="color: rgba(0, 0, 0, 1)">.finish) {
      message.success(``);
      setLoading(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
    }
    </span><span style="color: rgba(0, 0, 255, 1)">return</span> { hasFinshed: resPolling.data?<span style="color: rgba(0, 0, 0, 1)">.finish };
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> eslint-disable-next-line react-hooks/exhaustive-deps</span>
<span style="color: rgba(0, 0, 0, 1)">}, );
const </span>= usePolling(submitPublicBagPolling); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">接口轮询hook</span>
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)"> ========== 导入 ========== </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
const submitPublicBag </span>= async (values) =&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (Object.keys(values).length == 0<span style="color: rgba(0, 0, 0, 1)">) {
      setPublicBagVis(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    setLoading(</span><span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">);
    let res </span>= await axios.post("/batchsms/contact/crowdpack/submit"<span style="color: rgba(0, 0, 0, 1)">, {
      ...values,
      id: id,
    });
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (!<span style="color: rgba(0, 0, 0, 1)">res) {
      setLoading(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> <span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">;
    }
    </span><span style="color: rgba(0, 0, 255, 1)">if</span> (res.data?<span style="color: rgba(0, 0, 0, 1)">.finish) {
      message.success(``);
      setLoading(</span><span style="color: rgba(0, 0, 255, 1)">false</span><span style="color: rgba(0, 0, 0, 1)">);
    } </span><span style="color: rgba(0, 0, 255, 1)">else</span><span style="color: rgba(0, 0, 0, 1)"> {
      doPollingType();
    }
};</span></pre>
</div>
<p>&nbsp;</p>
<p>参考:https://juejin.cn/post/7085174569484582925</p>

</div>
<div id="MySignature" role="contentinfo">
    <p>本文来自博客园,作者:Janni,转载请注明原文链接:https://www.cnblogs.com/janni/p/16337021.html</p><br><br>
来源:https://www.cnblogs.com/janni/p/16337021.html
頁: [1]
查看完整版本: react hook 接口轮询