在前端开发中,经常会遇到需要下载多个文件的情况,例如下载多张图片、多个文档等。如果每个文件都单独下载,会浪费大量时间和带宽资源。因此,实现批量下载功能十分必要。
本文将介绍如何使用 ES2020 中的新特性 Promise.allSettled
和 Blob
,以及 XMLHttpRequest
的 onprogress
事件,来实现批量下载功能及进度显示。
实现批量下载功能
生成下载链接
首先,我们需要生成每个文件的下载链接。如果是后端提供的下载链接,可以直接使用;如果需要前端生成下载链接,则可以使用 Blob
对象。
-- -------------------- ---- ------- ----- ----------- - ----- -- - ------ --- ----------------- ------- -- - ----- --- - --- ----------------- --------------- ---- ------ ---------------- - ------- ---------- - -- -- - -- ----------- --- ---- - ----- ---- - --- --------------------- ----- --- - -------------------------- ------------- - ---- - ----------------------- - -- ----------- - -- -- - ----------------------- -- ----------- --- --
上面的代码中,downloadUrl
函数接收一个文件的 URL,使用 XMLHttpRequest
发送 GET 请求获取文件内容,并将其转化为 Blob
对象,最后使用 URL.createObjectURL
生成下载链接。
批量下载文件
有了每个文件的下载链接,我们就可以使用 Promise.allSettled
批量下载文件了。
const downloadAll = async (urls) => { const promises = urls.map(downloadUrl); const results = await Promise.allSettled(promises); const downloads = results.filter(result => result.status === 'fulfilled').map(result => result.value); return downloads; };
上面的代码中,downloadAll
函数接收一个下载链接数组 urls
,使用 map
方法将每个链接传递给 downloadUrl
函数,生成下载链接的 Promise 数组。使用 Promise.allSettled
等待所有 Promise 完成,并返回 Promise 结果数组 results
。筛选出状态为 fulfilled
的 Promise 结果,提取下载链接数组 downloads
,最后返回。
示例代码
下面是一个示例代码,实现了一个批量下载图片的功能。用户可以输入多个图片链接,点击下载按钮,即可批量下载图片并显示下载进度。
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- --------------------- ------- ------ --------------- ----- ------------------------------- --------- --------------------- ------ ----- ------- ------------------------- ------ ---- -------------------- -------- ----- ----------- - ----- -- - ------ --- ----------------- ------- -- - ----- --- - --- ----------------- --------------- ---- ------ ---------------- - ------- ---------- - -- -- - -- ----------- --- ---- - ----- ---- - --- --------------------- ----- --- - -------------------------- ------------- - ---- - ----------------------- - -- ----------- - -- -- - ----------------------- -- ----------- --- -- ----- ----------- - ----- ------ -- - ----- -------- - ---------------------- ----- ------- - ----- ----------------------------- ----- --------- - --------------------- -- ------------- --- ----------------------- -- -------------- ------ ---------- -- ----- -------------- - ------------------------------------ ----- ----------- - ------------------------------------ ---------------------------------------- ----- -- -- - ----- ------------ - -------------------------------- ----- ---- - -------------------------------------- -- ---------------------- -- --- --- ---- -- ------------ --- -- - --------------------- ------- - ----------------------- - ----- --------------------- - ---------- ----- --------- - ----- ------------------ ----- --- - --- -------- ---------------------------- ------ -- - ----- -------- - ------------- - -------- ------------------ ----------------------- - ------- ---- --- --- ----- ------- - ----- ------------------- ----- ------ --- ----- ------ - ----------------------------- ----- - - ---------------------------- ------ - ------- ---------- - ------------- ---------- ---------------------------- ----------------------- - ------ --------------------- - ------- --- --------- ------- -------
实现进度显示
上述代码可以实现批量下载功能,但是没有显示下载进度。为了实现进度显示,我们需要使用 XMLHttpRequest
的 onprogress
事件。
-- -------------------- ---- ------- ----- ----------- - ----- ----------- -- - ------ --- ----------------- ------- -- - ----- --- - --- ----------------- --------------- ---- ------ ---------------- - ------- ---------- - -- -- - -- ----------- --- ---- - ----- ---- - --- --------------------- ----- --- - -------------------------- ------------- - ---- - ----------------------- - -- ----------- - -- -- - ----------------------- -- -------------- - ------- -- - -- ------------------------ - ------------------------ ------------- - -- ----------- --- --
上面的代码中,downloadUrl
函数新增了一个参数 onProgress
,表示下载进度的回调函数。在 XMLHttpRequest
的 onprogress
事件中,如果 event.lengthComputable
为 true
,则调用 onProgress
函数,传递已下载字节数和总字节数。
为了在页面上显示下载进度,我们可以在 downloadButton
的 click
事件中加入以下代码:
-- -------------------- ---- ------- ----- ----------- - ------------------------------------ ----- ----------- - ------------------------------ ----------------------- - ----- ------------------------ - ------- --------------------------------- - -------- ---------------------------- - ------ ------ --------------------- - --- ------------------------------------- ----- ---------- - -------- ------ -- - ----- ------- - ----------------- - ----- - ----- ----------------------- - ------- - ---- --------------------- - ------- - ---- -- ----- --------- - ----- ----------------- ------------
上面的代码中,我们创建了一个进度条 progressBar
,并将其添加到 progressDiv
中。在 downloadAll
函数中传递了进度回调函数 onProgress
,在回调函数中计算下载进度并更新进度条的宽度和文本。
示例代码
下面是一个示例代码,实现了批量下载图片的功能,并显示下载进度。
-- -------------------- ---- ------- --------- ----- ------ ------ ----- ---------------- --------------------- ------- ------ --------------- ----- ------------------------------- --------- --------------------- ------ ----- ------- ------------------------- ------ ---- -------------------- -------- ----- ----------- - ----- ----------- -- - ------ --- ----------------- ------- -- - ----- --- - --- ----------------- --------------- ---- ------ ---------------- - ------- ---------- - -- -- - -- ----------- --- ---- - ----- ---- - --- --------------------- ----- --- - -------------------------- ------------- - ---- - ----------------------- - -- ----------- - -- -- - ----------------------- -- -------------- - ------- -- - -- ------------------------ - ------------------------ ------------- - -- ----------- --- -- ----- ----------- - ----- ------ ----------- -- - ----- -------- - ------------ -- ---------------- ------------- ----- ------- - ----- ----------------------------- ----- --------- - --------------------- -- ------------- --- ----------------------- -- -------------- ------ ---------- -- ----- -------------- - ------------------------------------ ---------------------------------------- ----- -- -- - ----- ------------ - -------------------------------- ----- ---- - -------------------------------------- -- ---------------------- -- --- --- ---- -- ------------ --- -- - --------------------- ------- - ----------------------- - ----- ----- ----------- - ------------------------------------ ----- ----------- - ------------------------------ ----------------------- - ----- ------------------------ - ------- --------------------------------- - -------- ---------------------------- - ------ ------ --------------------- - --- ------------------------------------- ----- ---------- - -------- ------ -- - ----- ------- - ----------------- - ----- - ----- ----------------------- - ------- - ---- --------------------- - ------- - ---- -- ----- --------- - ----- ----------------- ------------ ----- --- - --- -------- ---------------------------- ------ -- - ----- -------- - ------------- - -------- ------------------ ----------------------- - ------- ---- --- --- ----- ------- - ----- ------------------- ----- ------ --- ----- ------ - ----------------------------- ----- - - ---------------------------- ------ - ------- ---------- - ------------- ---------- ---------------------------- ----------------------- - ------ --------------------- - --- --- --------- ------- -------
总结
本文介绍了如何使用 ES2020 中的新特性 Promise.allSettled
和 Blob
,以及 XMLHttpRequest
的 onprogress
事件,来实现批量下载功能及进度显示。通过本文的示例代码,读者可以学习如何在前端实现批量下载功能,并加入下载进度的显示,提高用户体验。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/663719a7d3423812e453e18c