如何用JavaScript逐个下载多文件并查看下载进度?
实现串行下载文件并打包ZIP
要解决并行下载导致日志混乱、无法跟踪进度的问题,核心是把原来的并行Promise执行改成串行异步流程,确保每个文件下载完成后再启动下一个。以下是修改后的完整代码:
async function downloadFiles(urls) { const zip = new JSZip(); const totalCount = urls.length; async function downloadFile(url, index) { const fileName = url.split('/').pop(); console.log(`正在下载第 ${index + 1}/${totalCount} 个文件:${fileName}`); return new Promise((resolve, reject) => { JSZipUtils.getBinaryContent(url, (err, data) => { if (err) { console.error(`下载文件 ${fileName} 失败:`, err); reject(err); } else { zip.file(fileName, data, { binary: true }); console.log(`文件 ${fileName} 下载完成`); resolve(); } }); }); } // 串行遍历,逐个下载文件 for (let i = 0; i < urls.length; i++) { await downloadFile(urls[i], i); } console.log("所有文件下载完成,开始生成ZIP包"); const content = await zip.generateAsync({ type: "blob" }); saveAs(content, "Fichiers.zip"); console.log("ZIP包已生成并触发下载"); } function main() { const allLinks = document.getElementsByTagName('a'); const hrefs = []; for (let i = 0; i < allLinks.length; i++) { // 用endsWith替代substr,语义更清晰 if (allLinks[i].href.endsWith(".pdf")) { hrefs.push(allLinks[i].href); } } // 捕获整体流程的错误 downloadFiles(hrefs).catch(err => { console.error("下载流程出现异常:", err); }); } main();
关键改动说明:
- 将
downloadFiles声明为async函数,允许内部使用await控制异步流程的顺序 - 替换原有的
forEach+Promise.all为for循环配合await,强制实现串行下载,每个文件完成后才会开始下一个 - 新增进度索引参数,日志中显示当前下载的文件序号和总数量,进度跟踪更直观
- 用
endsWith(".pdf")替代substr(-4),代码可读性更高 - 增加全局错误捕获,避免单个文件下载失败导致整个流程直接中断
- 优化日志内容,让每个阶段的状态更清晰
内容的提问来源于stack exchange,提问作者Vivien Mirebeau
相关产品推荐
相关产品推荐

