如何使用 JSZip 同步生成 zip 文件?
How to generate a zip file synchronously using JSZip?
我正在开发一个 React.js 应用程序,我有一个从 j=1 到 j=2000 的循环我想在 j=1 或 j=2000 时下载一个 zip 文件。
问题是循环结束后同时下载了两个zip文件。换句话说,两个 zip 的下载在 j = 2000 时开始。
我尝试使用 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!!
这里的问题不在于 generateAsync 方法,而在于 saveAs,它被延迟到 cpu 可用并且无法等待,如此处所报告的:
https://github.com/eligrey/FileSaver.js/issues/389
一个解决方案可能是根本不等待,而是将循环转换为异步事件,让浏览器有时间在迭代之间显示保存对话框:
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>
请注意,由于安全限制,上述代码在 fiddle 中不起作用,您必须将其放在其他地方。
我正在开发一个 React.js 应用程序,我有一个从 j=1 到 j=2000 的循环我想在 j=1 或 j=2000 时下载一个 zip 文件。
问题是循环结束后同时下载了两个zip文件。换句话说,两个 zip 的下载在 j = 2000 时开始。
我尝试使用 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!!
这里的问题不在于 generateAsync 方法,而在于 saveAs,它被延迟到 cpu 可用并且无法等待,如此处所报告的:
https://github.com/eligrey/FileSaver.js/issues/389
一个解决方案可能是根本不等待,而是将循环转换为异步事件,让浏览器有时间在迭代之间显示保存对话框:
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>
请注意,由于安全限制,上述代码在 fiddle 中不起作用,您必须将其放在其他地方。