Skip to content

Commit efac90e

Browse files
committed
增加分片段下载,增加请求数限制
1 parent 4026a39 commit efac90e

File tree

1 file changed

+75
-29
lines changed

1 file changed

+75
-29
lines changed

src/download.js

Lines changed: 75 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import md5 from 'md5'
22
import JSZip from 'jszip'
33
import FileSaver from 'jszip/vendor/FileSaver'
4-
const noop = (func, defaultFunc) => {
4+
5+
// 每段数量上限
6+
export const partLimit = 1e3
7+
// 同时请求数上限
8+
export const requestLimit = 5
9+
10+
export const noop = (func, defaultFunc) => {
511
return typeof func === 'function' ? func : typeof defaultFunc === 'function' ? defaultFunc : () => {}
612
}
713

8-
const ajax = (options) => {
14+
export const ajax = (options) => {
915
var xhr = new XMLHttpRequest()
1016
options.method = options.method || 'get'
1117
xhr.responseType = options.dataType || 'json';
@@ -32,39 +38,79 @@ const ajax = (options) => {
3238
}
3339
}
3440

35-
export const downloadZip = (fileName, files) => {
36-
fileName = fileName || md5(files.map(item => item.downloadUrl).join('|'))
37-
const zip = new JSZip()
38-
const fetchFile = (file) =>{
39-
return new Promise((resolve, reject) => {
40-
if (file.content) {
41-
const blob = new Blob([file.content], {type : file.type || 'text/plain'})
42-
zip.file(file.name, blob)
43-
resolve(blob)
44-
} else {
45-
ajax({
46-
url: file.downloadUrl,
47-
type: 'get',
48-
data: '',
49-
dataType: 'blob',
50-
success: (blob) => {
51-
zip.file(file.name, blob);
52-
resolve(blob)
53-
},
54-
error: reject
41+
export const fetchBlobFile = (file) =>{
42+
return new Promise((resolve, reject) => {
43+
if (file.content) {
44+
resolve(new Blob([file.content], {type : file.type || 'text/plain'}))
45+
} else {
46+
ajax({
47+
url: file.downloadUrl,
48+
type: 'get',
49+
data: '',
50+
dataType: 'blob',
51+
success: (blob) => {
52+
resolve(blob)
53+
},
54+
error: () => {
55+
resolve(new Blob([file.downloadUrl], {type : 'text/plain'}))
56+
}
57+
})
58+
}
59+
})
60+
}
61+
62+
export const partTask = (items, handler, num = requestLimit) => {
63+
let index = 0
64+
let list = items.slice(0)
65+
let queue = Promise.resolve()
66+
const result = []
67+
while (list.length) {
68+
const current = list.splice(0, num)
69+
const currentIndex = index++
70+
queue = queue.then(() => {
71+
return new Promise((resolve) => {
72+
Promise.all(handler(current, currentIndex)).then(datas => {
73+
result.push.apply(result, datas)
5574
})
56-
}
75+
.finally(() => resolve(result))
76+
})
5777
})
5878
}
59-
return Promise.all(
60-
files.map(file => fetchFile(file))
61-
).then((datas) => {
62-
zip.generateAsync({
79+
return queue
80+
}
81+
82+
export const partRequest = (fileName, files) => {
83+
const zip = new JSZip()
84+
const handler = (files) => files.map(file => fetchBlobFile(file, zip).then(blob => {
85+
zip.file(file.name, blob)
86+
return blob
87+
}))
88+
return partTask(files, handler, requestLimit).then((datas) => {
89+
return zip.generateAsync({
6390
type: "blob"
64-
}).then(function(content) {
65-
FileSaver(content, fileName + '.zip');
91+
}).then((content) => {
92+
return new Promise((resolve) => {
93+
FileSaver(content, fileName);
94+
setTimeout(() => {
95+
resolve()
96+
}, 1.5e4)
97+
})
6698
})
6799
})
68100
}
69101

102+
export const partDownload = (fileName, files) => {
103+
const count = ~~(files.length / partLimit)
104+
return partTask(files, (files, index) => {
105+
const partMame = count >= 1 ? '-p' + (index + 1) + '-' + count : ''
106+
const name = fileName + partMame + '.zip'
107+
return [partRequest(name, files)]
108+
}, partLimit)
109+
}
110+
111+
export const downloadZip = (fileName, files) => {
112+
fileName = fileName || md5(files.map(item => item.downloadUrl).join('|'))
113+
return partDownload(fileName, files)
114+
}
115+
70116
export default downloadZip

0 commit comments

Comments
 (0)