TA的每日心情 | 衰 2024-5-10 14:44 |
---|
签到天数: 23 天 [LV.4]偶尔看看III
初级工程师
- 积分
- 64
|
悬赏15油猫币已解决
本帖最后由 ThisAV 于 2022-1-25 14:04 编辑
https://www.xiurenji.net/XiuRen/5409.html
- //获取图片生成
- let currentPageID=location.href.match(/(\d+)(?:_\d+)?.html/)[1],
- pageMax=$('.page>a:last').text()=='下页'?$('.page>a:last').prev().text():$('.page>a:last').text();
- let ImgList=[];
- async function getImgUrl(array){
- const ret = [];
- const executing = [];
- return new Promise(async (resolve, reject) => {
- try {
- for(let currentPage=0;currentPage<(+pageMax);currentPage++) {
- let PageID = currentPage==0 ? `/${currentPageID}.html` : `/${currentPageID}_${currentPage}.html`,
- PageUrl = location.pathname.replace(/\/[^/.]+\.html/i, PageID);
- await $.get(PageUrl, (res,s,e)=>{
- $('.content img', res).map(function(i, e){
- ImgList.push(this.src);
- //console.log(PageID, i, e, this.src)
- });
- })
- }
- } catch(e){
- console.error(e);
- } finally {
- Promise.all(ret);
- }
- })
- }
- getImgUrl();
- let padZero = (n) => (num) => {
- if (typeof num === 'number') num += '';
- return num.padStart(n, '0');
- }
- function requestUrlBlob(url) {
- return new Promise((resolve, reject) => {
- GM_xmlhttpRequest({
- url: url,
- method: 'get',
- responseType : 'blob',
- onload : res => resolve(res.response),
- onerror : e => reject(e)
- });
- })
- }
- async function downloadAndPackFile(zipPack, url, filename, extname) {
- if (!extname) {
- const urlExt = url.split('.').pop();
- extname = urlExt ? `.${urlExt}` : '';
- }
- console.log(`正在下载`, url, filename);
- await requestUrlBlob(url).then((blob) => {
- console.log(`下载完成`, url, blob, filename);
- zipPack.file(`${filename}${extname}`, blob);
- });
- }
- async function startDownload(ImgList, zipName) { // zipName = 压缩包名字
- const zipPack = new window.JSZip();
- const urlObjList = ImgList.map((url, idx) =>({url, filename: padZero(3)(idx),}));
- console.log('开始下载');
- await asyncPool(5, urlObjList, ({ url, filename }) => {
- downloadAndPackFile(zipPack, url, filename);
- });
- await zipPack.generateAsync({ type: 'blob' }, function(metadata) {
- let progress = metadata.percent / 100;
- console.log(metadata, progress);
- }).then(
- function (blob) {
- // 1) generate the zip file
- window.saveAs(blob, `${zipName}.zip`); // 2) trigger the download
- },
- function (err) {
- console.error('[批量下载] ERR', err);
- }
- );
- console.log('资源下载完成,开始打包资源', zipName);
- }
- async function asyncPool(poolLimit, array, iteratorFn) { //通过任务池限制并发数量,任务池 poolLimit=任务上限,array=任务对象,iteratorFn=任务内容
- const ret = [];
- const executing = [];
- for (const item of array) {
- const task = Promise.resolve().then((y, n) => {
- iteratorFn(item, array)
- }); //等待处理完成
- ret.push(task);
- console.log(task);
- if (poolLimit <= array.length) {
- const e = task.then(() => executing.splice(executing.indexOf(e), 1));
- executing.push(e);
- if (executing.length >= poolLimit) {
- await Promise.race(executing);
- }
- }
- }
- return Promise.all(ret);
- }
-
复制代码
对 Promise 不太熟悉,如上面的地址
startDownload 函数里
asyncPool 负责下载图片和打包
zipPack.generateAsync 执行下载动作
但是 zipPack.generateAsync 没有等待 asyncPool 的 GM_xhr 完成就执行了下载动作,导致下载了一个空包
该怎么调整代码执行?
|
最佳答案
查看完整内容
感觉你对async/await的理解有问题,虽然强行异步后返回值变成了Promise,但代码实际还是同步的,这个downloadAndPackFile函数问题很大,return GM_xhr肯定得不到想要的结果,应该自己用Promise封装后return这个Promise(参考我给的download函数),asyncPool做的事跟我的downloadAll函数类似。
|