JavaScript 中如何实现大文件并行下载
JavaScript 中如何实现大文件并行下载
在前端开发中,下载大文件时常常会遇到速度慢、易中断等问题。通过并行下载(分片下载),可以显著提升下载速度和稳定性。本文将详细介绍原理、使用场景,并结合完整实例代码,帮助你在实际项目中高效实现大文件并行下载。
一、原理简介
- 分片下载:将大文件分割为多个片段(chunk),每个片段单独请求。
- 并行请求:利用浏览器的并发能力,同时发起多个请求下载不同片段。
- 合并文件:所有片段下载完成后,按顺序合并为完整文件。
二、适用场景
- 前端需要下载大体积文件(如视频、安装包、数据包等),提升下载速度。
- 需要支持断点续传、容错重试,提升下载稳定性。
- 服务器支持 HTTP Range 请求。
- CDN 或后端带宽充足,允许多并发请求。
常见应用:
- 云盘、网盘类产品的文件下载
- 视频、音频等大文件分片下载
- 前端批量数据导出
三、完整实例代码
下面以一个实际可运行的例子,演示如何并行下载大文件并合并:
/*** 并行下载大文件示例* @param {string} url 文件下载地址* @param {string} filename 下载保存的文件名* @param {number} chunkSize 每个分片大小(字节),如 1MB = 1024*1024* @param {number} concurrency 并发数,建议 4~8*/
async function parallelDownload(url,filename,chunkSize = 1024 * 1024,concurrency = 4
) {// 1. 获取文件总大小const headRes = await fetch(url, { method: "HEAD" });const totalSize = Number(headRes.headers.get("content-length"));if (!totalSize) throw new Error("无法获取文件大小");// 2. 生成分片区间const ranges = [];for (let i = 0; i < totalSize; i += chunkSize) {ranges.push([i, Math.min(i + chunkSize - 1, totalSize - 1)]);}// 3. 并发下载分片const buffers = new Array(ranges.length);let downloading = 0,next = 0;return new Promise((resolve, reject) => {function downloadNext() {if (next >= ranges.length) {if (downloading === 0) {// 全部下载完成,合并const totalBuffer = new Uint8Array(totalSize);let offset = 0;buffers.forEach((buffer) => {totalBuffer.set(new Uint8Array(buffer), offset);offset += buffer.byteLength;});// 生成下载链接const blob = new Blob([totalBuffer]);const link = document.createElement("a");link.href = URL.createObjectURL(blob);link.download = filename;link.click();resolve();}return;}const idx = next++;downloading++;const [start, end] = ranges[idx];