简体   繁体   English

如何使用JSZip同步生成一个zip文件?

[英]How to generate a zip file synchronously using JSZip?

I'm working on a React.js application, i have a loop from j=1 to j=2000 and i want to download a zip file when j=1 or j=2000.我正在开发一个 React.js 应用程序,我有一个从j=1j=2000的循环,我想在 j=1 或 j=2000 时下载一个 zip 文件。

The problem is that the two zip files downloaded at the same time after the end of the loop.问题是循环结束后两个zip文件同时下载。 in other words the download of the two zip starts when j = 2000.换句话说,两个 zip 的下载在 j = 2000 时开始。

I tried to make the zip generation synchronous by using async and await, but it didn't work for me.我试图通过使用 async 和 await 使 zip 生成同步,但它对我不起作用。

 const generateCollection = async ()=>{ for(var j = 1; j <= 2000; j++){ let zip = new JSZip(); let metadata = zip.folder("metadata"); const obj = {name: "Simple name", age: "Simple age"} metadata.file(`1.json`, JSON.stringify(obj, null, 4)) console.log("Start Downloading: ", j) if(j===1 || j===2000){ await zip.generateAsync({type:"blob"}) .then(content=>{ setIsLoading(false) FileSaver.saveAs(content, `collection_${j}.zip`); console.log("Saved...... ", j) }) } } }

I will appreciate any help, or suggestion!!我将不胜感激任何帮助或建议!!

The problem here is not with the generateAsync method, but rather with the saveAs, which is delayed until the cpu is available and cannot be awaited as reported here:这里的问题不在于 generateAsync 方法,而在于 saveAs,它被延迟到 cpu 可用并且不能像这里报告的那样等待:

https://github.com/eligrey/FileSaver.js/issues/389 https://github.com/eligrey/FileSaver.js/issues/389

A solution could be to don't await at all, but instead convert the loop into an async event to give the browser the time to show the save dialog between the iterations:一个解决方案可能是根本不等待,而是将循环转换为异步事件,让浏览器有时间在迭代之间显示保存对话框:

 const generateCollection = ()=> { var j = 1; const loop = function() { if (j <= 2000) { let j2 = j; //Create a local copy of the loop var let zip = new JSZip(); let metadata = zip.folder("metadata"); const obj = {name: "Simple name", age: "Simple age"}; metadata.file(`1.json`, JSON.stringify(obj, null, 4)); console.log("Start Downloading: ", j) if (j2===1 || j2===2000){ zip.generateAsync({type:"blob"}) .then(content=>{ saveAs(content, `collection_${j2}.zip`); console.log("Saved...... ", j2) }); } j++; setTimeout(loop, 0); } }; setTimeout(loop, 0); } $(function() { generateCollection(); });
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>

Note that the above code doesn't work within the fiddle due to security restrictions, you have to put it somewhere else.请注意,由于安全限制,上面的代码在 fiddle 中不起作用,您必须将其放在其他地方。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM