我正在尝试编写一个函数,该函数加载包含多个其他zip文件的zip文件,对其进行迭代,然后提取找到的所有csv文件以合并并将结果提取到一个聚合的csv中。我遇到的问题是我无法使用异步将csv的内容映射到其文件名或目录。这是一个片段,其中myzip2是JSZIP对象,文件是文件名的字典,而csvfiles是我的输出数组。
for (var key in files) {
if ( files[key].name.includes('.csv') ) {
myzip2.file( files[key].name ).async("string").then( function(result) {
csvfiles.push( $.csv.toArrays(result) ); // contains the csv content
csvfiles.push( files[key].name ); // undefined in async
});
)
)
我想同时推送csv内容和文件名,但是文件名在函数内部未定义。我怎么才能得到它?我没有太多机会来研究我的问题,我可能缺少正确的措词。
谢谢
如果有人遇到相同的问题,则将文件名与内容匹配是由箭头函数解决的闭包问题,但是将正确的zipfile名称匹配是将JSZip追加到当前对象的问题。new JSZip()
如果您需要清除旧的,请使用。
完整代码zipfiles是mainzip中包含的zipfiles名称列表
var csvfiles = []
for (var i = 0; i < zipfiles.length; i++) {
let thiszipname = zipfiles[i];
let thiszip = mainzip.file( thiszipname ).async("blob");
var newzip = new JSZip();
newzip.loadAsync( thiszip ).then(
subzip => {
let subfiles = subzip.files;
Object.keys(subfiles).forEach( filename => {
if ( filename.includes('.csv') ) {
subzip.file( filename ).async("string").then(
readData => {
var obj = $.csv.toObjects(readData); // works great
obj['csvfile'] = filename // correct file
obj['zipfile'] = thiszipname; // incorrect zipfile...
csvfiles.push( obj );
}
);
}
})
}
)
} console.log(csvfiles)
问题与files
变量的词法范围有关。与无关async
。
闭包是捆绑在一起(封闭)的函数及其周围状态(词汇环境)的组合。换句话说,闭包使您可以从内部函数访问外部函数的范围。在JavaScript中,每次创建函数时都会在函数创建时创建闭包。
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures
在循环中执行此操作时,需要注意“循环闭合”问题。
请在同一链接下查看“在循环中创建闭包:常见错误”部分:https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
您应该将匿名函数替换为箭头函数,它将起作用。
for (var key in files) {
// It's important to set the value of the `files[key]` to the separate variable.
// Because otherwise the last element of the `files` will be captured in the closure for the expression `files[key]`.
const fileName = files[key].name;
myzip2
.file(fileName)
.async("string")
// Arrow function `result => {}` creates a closure that captures `fileName` variable from the external scope
.then(result => {
csvfiles.push($.csv.toArrays(result));
csvfiles.push(fileName);
});
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句