【问题标题】:Axios onDownloadProgress (on get method) gets called only once and setTimeout in callback never gets calledAxios onDownloadProgress(在get方法上)只被调用一次,回调中的setTimeout永远不会被调用
【发布时间】:2021-07-29 07:31:02
【问题描述】:

我试图在从后端获取 API 时显示进度条。它似乎有效,但是有几个我无法解决的问题。 a) 进度条从 0 变为 100,并且不显示任何进度,因为 onDownloadProgress 仅被触发一次。 b) 我想要 setTimeout,因为有时加载 API 的速度非常快,以至于在应用程序开始运行后进度条就消失了。我天真地认为 setTimeout 可以防止这个问题,因为我可以在获取 API 完成后暂停整个过程。由于 setTimeout 永远不会被触发,因此加载保持为真并且进度条永远不会消失。

const [loading, setLoading] = useState(false);
const [progress, setProgress] = useState(0);
useEffect(() => {
    // grab rooms from back end
    fetchRooms();
  }, []);

const fetchRooms = async () => {
    try {
      setLoading(true);
      const res = await axios.get(`${ENDPOINT}/api/rooms`, {
        onDownloadProgress: (progressEvent) => {
          setProgress(Math.round((progressEvent.loaded * 100) / totalLength));
          if (progress === 100) {
            setTimeout(() => {
              console.log("load finished!////////");
              setLoading(false);
            }, 2000);
          }
        },
      });
     
      setRooms(res.data);
      // having setLoading here dose not work as progress bar disappears right after application starts to run if loading is too fast
      // setLoading(false);
    } catch (err) {
      console.log(err);
      setProgress(0);
    }
  };

【问题讨论】:

    标签: javascript reactjs ajax axios progress-bar


    【解决方案1】:

    您可以在 setProgress 函数中设置 setInterval JavaScript 函数,以及一个 html 进度标记。以下是如何使用您的一些代码的示例。 list.json 文件只是一个对象数组。

    import { useState, useEffect } from "react";
    import axios from "axios";
    
    const ENDPOINT =
      "./list.json";
    
    function App() {
      const [loading, setLoading] = useState(false);
      const [rooms, setRooms] = useState([]);
      const [progress, setProgress] = useState(0);
      useEffect(() => {
        // grab rooms from back end
        fetchRooms();
      }, [progress]);
    
      const fetchRooms = async () => {
        try {
          setLoading(true);
          const res = await axios.get(`${ENDPOINT}`, {
            onDownloadProgress: (progressEvent) => {
              var percentCompleted = Math.round((progressEvent.loaded * 100)/progressEvent.total);
              setProgress(setInterval(percentCompleted,10)) // progress is set every 10 milliseconds
            },
          });
    
          setRooms(res.data.results);
          console.log(rooms);
          // having setLoading here dose not work as progress bar disappears right after application starts to run if loading is too fast
          // setLoading(false);
        } catch (err) {
          console.log(err);
          setProgress(0);
        }
      };
    
      if (loading) {
        return <progress value={progress} max="100"/>
      }
      return null;
    }
    
    export default App;
    

    参考资料:

    W3 学校。如何 - JavaScript 进度条。 https://www.w3schools.com/howto/howto_js_progressbar.asp。 (2021 年 5 月 7 日访问)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 1970-01-01
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 2014-06-22
      • 2015-07-28
      相关资源
      最近更新 更多