1.原理

需要显示下载进度per,就要知道文件的长度len和目前的进度proper = pro / len

len:文件的长度通过返回值中的response.headers.get('Content-Length')

pro:

主要使用fetchresponse.body属性,它是ReadableStream的一个特殊对象,可以逐块(chunk)提供body,即是将一次返回的数据按块返回

我们可以使用它实现对进度读取的完全控制,以用来计当前下载进去

2.Step

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// step 1:
// 启动 fetch,并获得一个 reader
let response = await fetch('');
const reader = response.body.getReader();
// step 2:
// 获得总长度(len)
const len = +response.headers.get('Content-Length');
// step 3:读取数据
let pro = 0; // 当前接收到了这么多字节
let chunks = []; // 接收到的二进制块的数组(包括 body)
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
chunks.push(value);
pro += value.length;
console.log(`Received ${pro} of ${len}`)
}
// step 4:将块连接到单个 Uint8Array
let chunksAll = new Uint8Array(pro); // (4.1)
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position); // (4.2)
position += chunk.length;
}
// step 5:解码成字符串
let result = new TextDecoder("utf-8").decode(chunksAll);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fetch(
"url",
{
method: "POST",
body: JSON.stringify{{}},
dataType: "text"
}
).then((response) => {
// 代替 response.json() 以及其他方法
const reader = response.body.getReader();
// 在 body 下载时,一直为无限循环
while(true) {
// 当读取完成时为 true,否则为 false
// value 字节的类型化数组:Uint8Array
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
fetch(
"url",
{
method: "POST",
body: JSON.stringify{{}},
dataType: "text"
}
).then((response) => {
// 代替 response.json() 以及其他方法
const reader = response.body.getReader();
// 在 body 下载时,一直为无限循环
while(true) {
// 当读取完成时为 true,否则为 false
// value 字节的类型化数组:Uint8Array
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Step 1:启动 fetch,并获得一个 reader
let response = await fetch('https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100');
const reader = response.body.getReader();
// Step 2:获得总长度(length)
const contentLength = +response.headers.get('Content-Length');
// Step 3:读取数据
let receivedLength = 0; // 当前接收到了这么多字节
let chunks = []; // 接收到的二进制块的数组(包括 body)
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
chunks.push(value);
receivedLength += value.length;
console.log(`Received ${receivedLength} of ${contentLength}`)
}
// Step 4:将块连接到单个 Uint8Array
let chunksAll = new Uint8Array(receivedLength); // (4.1)
let position = 0;
for(let chunk of chunks) {
chunksAll.set(chunk, position); // (4.2)
position += chunk.length;
}
// Step 5:解码成字符串
let result = new TextDecoder("utf-8").decode(chunksAll);
// 我们完成啦!
let commits = JSON.parse(result);

最后更新: 2024年01月16日 14:59