批量下载踩坑记录-默认下载最后一个文件

背景

最近有个需求,希望实现批量下载功能。不涉及后端接口,前端直接拿文件路径下载,踩了2个坑,特此记录,抚慰心灵。

遇到的问题

  1. 一开始直接循环,下载,总是默认下载最后一个文件
  2. 使用setTimeout代码报错

实现

通过循环选中的路径数组,动态创建a标签,进行下载
初始代码(有问题)

// .vue文件
// js
import {  downloadFile } from '@/utils';
methods:{
	// 批量下载
	batchDownload(){
		paths.forEach((item,index) => {  // 循环路径数组
		   const url = `${basePicUrl}${item}` // 拼接出下载路径 eg:   http://10.110.xx:0000/img/a.zip
		         downloadFile(url,names[index])  // 执行下载方法(动态生成a标签方式)
		 })
	}
}

 
// util.js 文件 
// 下载
export function downloadFile(url,name) {
    const a = document.createElement('a')
    a.download = name || new Date().getTime()
    a.href = url
    a.click()
    a.remove()
  }

结果总是默认下载最后一个文件,中间走了很多弯弯绕绕,以为是文件太大的原因,甚至去试了streamSaver.js(大文件下载处理,处理流文件,而我这里直接是文件存储路径下载),万万没想到啊,静下心来想想,发现方向都是错的。。
后来查到原因,当循环执行下载的时候,几个下载命令连续执行的时候,浏览器会取消上一个下载,直接下载最后一个文件。
所以要加一个定时器,让几个连续的下载请求之间有时间间隔
于是

paths.forEach((item,index) => {
   const url = `${basePicUrl}${item}` // 拼接出下载路径 eg:   http://10.110.xx:0000/img/a.zip
      setTimeout(downloadFile(url,names[index]),1000*index)
 })```

结果setTimeout上面的代码一直报错,就很奇怪,最后,是我setTimeout用错了,竟然用错了,我盲目自信了。。setTimeout回调函数传参不是我以为的方式
批量下载踩坑记录-默认下载最后一个文件_第1张图片
参考文章:https://zhuanlan.zhihu.com/p/110274000
setTimeout中this指向问题:https://wangdoc.com/javascript/async/timer

修改后代码(正确)

paths.forEach((item,index) => {
   const url = `${basePicUrl}${item}` // 拼接出下载路径 eg:   http://10.110.xx:0000/img/a.zip
      setTimeout(()=>{  // 修改了setTimeout传参方式 
         downloadFile(url,names[index])
     },1000*index)
 })```


至此,完美,批量下载实现

你可能感兴趣的:(前端,javascript,vue.js)