fetch 监听接口进度,显示下载速度,结合el-progress实现下载进度可视化

效果图:

实现:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>fetch测试</title>
    <link rel="stylesheet" href="/css/element.css">
    <script src="/js/vue.min.js"></script>
    <script src="/js/element.js"></script>
    <script src="/js/jquery-3.5.1.min.js"></script>
    <style>
        body {
            margin: 0;
            padding: 0;
        }
    </style>
</head>

<body>
    <div id="fetchApp">
        <div style="margin: 200px auto;width: fit-content;display: flex;flex-direction: column;justify-content: center;">
            <div style="margin-bottom: 50px;">
                <el-progress type="circle" :percentage="count" :status="count==100?'success':''"></el-progress>
            </div>
            <div>
                下载速率:{{speed>1024?parseInt(speed/1024*100)/100:speed}} {{speed>1024?'MB/s':'KB/s'}}
            </div>
            <el-button type="primary" @click="download">{{btnName}}</el-button>
        </div>
    </div>
    <script>
        new Vue({
            el: '#fetchApp',
            data () {
                return {
                    btnName:'下载测试',
                    count:0,
                    speed:0,
                    time:0,
                }
            },
            mounted () {
                
            },
            methods: {
                async download(){

                    // get请求格式
                    let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits');

                    // post请求格式
                    // let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits',{
                    //     method: 'POST',
                    //     headers: {
                    //         'Content-Type': 'application/json;charset=utf-8'
                    //     },
                    //     body: JSON.stringify(user)
                    // });

                    const reader = response.body.getReader();
                    // 获得总长度(length)
                    const contentLength = +response.headers.get('content-length')
                    console.log(response.headers.get('content-length'));

                    // 读取数据
                    let receivedLength = 0; // 当前接收到了这么多字节
                    let chunks = []; // 接收到的二进制块的数组(包括 body)
                    while(true) {
                        const {done, value} = await reader.read();
                        if (done) {
                            break;
                        }
                        // 第一次时间戳为0,不测速
                        if(this.time){
                            // 获取下载当前数据所花费的时间
                            let ms = Date.now() - this.time
                            console.log(ms,value.length);
                            // 计算下载速度(KB/s)
                            this.speed = parseInt((value.length/(1024*8))/ms*1000)
                            // 保存当前的时间戳
                            this.time = Date.now()
                        }else{
                            this.time = Date.now()
                        }

                        chunks.push(value);
                        receivedLength += value.length;

                        this.count = parseInt(receivedLength/1572.24)
                        
                        console.log(`Received ${receivedLength} of ${contentLength}`)
                    }

                    // 将块连接到单个 Uint8Array
                    let chunksAll = new Uint8Array(receivedLength); 
                    let position = 0;
                    for(let chunk of chunks) {
                        chunksAll.set(chunk, position); 
                        position += chunk.length;
                    }

                    // 解码成字符串
                    let result = new TextDecoder("utf-8").decode(chunksAll);

                    let commits = JSON.parse(result);
                    console.log(commits);

                }
            }
        })
    </script>
</body>

</html>

  • 7
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值