如何在 Axios 的 GET 请求过程中展示进度(非下载或上传)

28
我希望在Axios获取我的请求时显示进度条。axios包有onDownloadProgressonUploadProgress用于在下载或上传过程中显示进度条,但没有在进行get请求时显示进度条。我搜索了很多问题和文章,但它们总是关于下载/上传进度或适用于Vue.js,并且我不知道如何在React中实现它。

我有以下代码(因为我没有下载,所以它不起作用)。

理想情况下,我想自己编写它; 但如果有人能够解释如何将loadProgressBar()与我的Axios请求集成,那么我愿意考虑使用axios-progress package
request = () => {
    this.setState({error: null, results: []})
    axios({
        method: 'get',
        url: process.env.REACT_APP_API_LOCALS,
        responseType: 'json',
        onDownloadProgress: (progressEvent) => {
            var percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total);
            this.setState({
                loading: percentCompleted
            })
        },
    })
    .then(
        (response) => {
            console.log(response)
            this.setState({
                results: response.data.results,
                error: null,
                totalPages: Math.ceil(response.data.count / response.data.results.length)
            })  
        }
    )
    .catch(
        (error) => {
            this.setState({
                loading: null,
                error: true
            })  
        }
    );
}
4个回答

34

以下是在React中为我起作用的:

const client = axios.create({
  baseURL: 'http://localhost:10000/v1/client',
  timeout: 20000
})

let result = await client.get('/fetchMeSomething', {
  onDownloadProgress: progressEvent => {
    const total = parseFloat(progressEvent.currentTarget.responseHeaders['Content-Length'])
    const current = progressEvent.currentTarget.response.length

    let percentCompleted = Math.floor(current / total * 100)
    console.log('completed: ', percentCompleted)
  }
})
.then(res => {
  console.log("All DONE: ", res.headers)
  return res.data
})

16
你还可以使用 let percentCompleted = Math.floor(progressEvent.loaded / progressEvent.total * 100),因此无需解析和查看头信息。 - modmoto

8
  axios
  .get("download something", {
    onDownloadProgress: (progressEvent) => {
      let downloadCount = DownloadCount(
        progressEvent.timeStamp,
        progressEvent.total,
        progressEvent.loaded
      );
      let percentCompleted = Math.round(
        (progressEvent.loaded * 100) / progressEvent.total
      );
      setProgressing(percentCompleted);
      dispatch({
        type: "downloading",
        payload: downloadCount.toFixed(1),
      });
    },
  })
  .then((response) => {})
  .catch((error) => {
    console.log(error);
  });


1

我认为 axios 既提供了 onUploadProgress 也提供了 onDownloadProgress 的原因是你可以方便地对传输的字节进行一些计算。对于简单的服务器请求,我认为可以使用一个标志位来设置

state = {
  loading: false
}

并且在您进行请求时将其翻转为 true 是理想的。如果您愿意,可以使用旋转器作为遮罩。


我知道如何制作旋转器,这确实很容易从false变为true。然而,我有至少7个页面需要请求大量数据。与其使用旋转器,我认为这种情况需要一个进度条,以便用户知道加载内容需要多长时间。 - Cédric Bloem
1
你有没有考虑使用 SuspenseReact.lazy?我认为在这种情况下这是正确的做法(如果我没错的话),随着用户导航,逐步加载页面而不是一次性全部加载。这也可以提高用户体验。 - tbuglc
我认为使用它肯定会很有趣!在这种情况下,我认为一个简单的旋转器就可以了。然而,因为我还没有在文章或Stackoverflow上找到对这个特定问题的答案,所以我会把它留给一段时间,这样未来遇到同样问题的React开发人员可以在这里找到解决方案。感谢Suspense / React.lazy提示!@tbuglc - Cédric Bloem
1
不客气。您可能会觉得Andrew Clark的演讲 Concurrent Rendering in React[https://www.youtube.com/watch?v=ByBPyMBTzM0] 很有趣。 - tbuglc

-2

我知道你要求一个进度条,但是我使用了这个教程来创建一个进度圆,利用svg圆形的stroke-dasharraystroke-dashoffset属性。

https://css-tricks.com/building-progress-ring-quickly/

整个项目都是用React完成的,所以对你来说应该是一个相当容易的实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接