Chome游览器下批量创建下载任务

2021-12-28 / 12 阅读 / Html

首先创建下载任务代码

实现代码千千万,都离不开标签

function urlToDown (url, name) {
    var link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', name);
    document.body.appendChild(link);
    link.dispatchEvent(new MouseEvent('click'));
    document.body.removeChild(link);
};
通常的批量创建任务,使用for或forEach等循环
list.forEach(item => {
    urlToDown(item)
})

这样带来的问题,犹如100个大货车想并排过桥一样,显然是不可取的,且不说桥能不能承受住所有的重量,宽度也是不够。

所以游览器可能也是出于此考虑,将短时间内创建的下载任务最大数设置为10。及哪怕list中有1000条,循环过后也只会有10条下载任务创建。

因此此循环创建任务的代码需要优化。那能否任务创建时的增加时间等待再执行下一任务了?

例如:

list.forEach(item => {
    setTimeOut(() => {
        urlToDown(item)
    },1000)
})

其实效果和第一种方式是一样的。只是整体延迟1000毫秒而已。最终还是只会创建10条。

针对javascript特性还是有几种解决方案的,着重讲解方案三

方案一:

setTimeOut + 迭代函数

方案二:

setInterval + 迭代函数

方案三:

此方案是封装自定义异步循环函数实现的,适应各种需要异步操作的业务。例如循环调用接口,优化并发问题。闲话不多说,上代码。

 // array为需要异步循环数组 
 // callBack为异步循环中的处理回调函数接受两个参数callBack(item, next)
 // finish为需要异步循环全部结束后的完成通知函数
 function arrayForAsync(array, callBack, finish) {
    (function loop(index) {
        if (index < array.length) {
            callBack(array[index], function () {
                loop(++index)
            })
        } else if (typeof finish === 'function') {
            finish();
        }
    })(0)
};

以上循环创建下载任务代码可改为:

 list.forAsync((item, next)  =>  {
     urlToDown(item)
     setTimeout(next, 1000);// 延迟1秒执行next下一处理任务
 }.bind(this));

当然以上setTimeout部分也可以是ajax请求,根据请求结果返回再执行next()。则实现异步循环任务。

小结

文档中代码都是复制上来手撸简化的,复制过去可能会有小的语法问题。简单处理一下即可。

相关推荐