要在浏览器中使用 Web Worker 线程显示下载进度,你需要做几件事情:
- 修改 Worker 以返回下载进度:你需要让 Worker 定期发送消息回主线程,报告下载的进度。
- 在主线程中更新进度:根据 Worker 发送的进度信息,更新 UI 显示下载进度。
下面是一个修改后的示例,展示如何显示下载进度。这个示例包括在主线程和 Worker 线程之间的通信。
主线程代码(JSP 页面中的 JavaScript)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Download with Progress</title>
</head>
<body>
<div id="progress-container">
<div id="progress-bar" style="width: 0%; background-color: green; text-align: center; color: white; padding: 1px;">0%</div>
</div>
<script>
const worker = new Worker('downloadWorker.js');
// 发送下载任务给 Worker
const urls = [/* 这里是100个附件的URL数组 */];
const batchSize = 10; // 同时下载的最大数量
let currentIndex = 0;
function startDownloads() {
for (let i = 0; i < batchSize && currentIndex < urls.length; i++) {
worker.postMessage({ url: urls[currentIndex], index: currentIndex });
currentIndex++;
}
}
worker.onmessage = function(event) {
const { index, progress, data, fileName } = event.data;
if (progress !== undefined) {
const totalDownloads = urls.length;
const overallProgress = ((index + 1) * batchSize + progress) / (totalDownloads * 100);
const progressBar = document.getElementById('progress-bar');
progressBar.style.width = `${Math.min(overallProgress * 100, 100)}%`;
progressBar.textContent = `${Math.min(overallProgress * 100, 100).toFixed(2)}%`;
} else if (data && fileName) {
const blobUrl = URL.createObjectURL(new Blob([data], { type: 'application/zip' }));
const a = document.createElement('a');
a.href = blobUrl;
a.download = fileName;
a.click();
URL.revokeObjectURL(blobUrl);
// 如果有更多文件需要下载,继续下载
if (currentIndex < urls.length) {
startDownloads();
}
}
};
// 开始下载
startDownloads();
</script>
</body>
</html>
Worker 线程代码(downloadWorker.js)
self.onmessage = function(event) {
const { url, index } = event.data;
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onprogress = function(e) {
if (e.lengthComputable) {
const progress = Math.round((e.loaded * 100) / e.total);
self.postMessage({ index, progress });
}
};
xhr.onload = function() {
if (xhr.status === 200) {
self.postMessage({ index, data: xhr.response, fileName: `file_${index}.zip` });
} else {
console.error(`Failed to download file ${index}: ${xhr.statusText}`);
}
};
xhr.onerror = function() {
console.error(`Error downloading file ${index}`);
};
xhr.send();
};
解释
主线程:
- 创建一个进度条容器。
- 使用 Web Worker 发送下载任务。
- 监听 Worker 发送的消息,更新进度条。
- 下载完成后,创建 Blob URL 并模拟点击
<a>
标签下载文件。 - 如果还有文件需要下载,继续发送下载任务。
Worker 线程:
- 接收下载任务(URL 和索引)。
- 使用
XMLHttpRequest
发起下载请求。 - 在
onprogress
事件中,计算并发送下载进度给主线程。 - 在
onload
事件中,发送下载的数据和文件名给主线程。
这样,你就可以在浏览器中显示下载进度了。