我想先说(来自c ++和python)我对JS很新,所以我欢迎任何关于我的代码的明智建议。
我希望使用HTML5文件API读取一些文件,然后用JS打开它们,执行一些操作并下载压缩的结果。我的问题是,读取文件似乎是一个异步操作,我真的没有看到一种优雅的方式等待它们全部完成然后压缩结果。
此处提供了一种可能的解决方案: https://stackoverflow.com/a/17491515 但我想知道一个人是否可以比使用全球旗帜更好。
我也遇到了从异步函数中检索结果的问题,因为我不知道如何在new_file_list
中找回changeCharsInFiles
。
谢谢!
代码示例: HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body >
<div class="container">
<div class="jumbotron">
<h3>Add Files Here</h3>
<input type="file" id="the-file-field" multiple>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.5/jszip.min.js"></script>
<script src="http://cdn.jsdelivr.net/g/filesaver.js"></script>
<script>
########### SEE JS BELOW #####################
</script>
</body>
JS:
if (window.File && window.FileReader && window.FileList && window.Blob) {
//functions
function zipMyFilesAndSave(file_list){
var zip = new JSZip();
for (var i = 0; i<file_list.length; i+=1)
{
zip.file(file_list[i].name, file_list[i] );
}
zip.generateAsync({type:"blob"}).then(
function (blob) {
saveAs(blob, "hello.zip");
},
function (err) {
jQuery("#blob").text(err);
});
}
function changeCharsInFiles(file_list){
var new_file_list = [];
for (var i = 0; i<file_list.length; i+=1)
{
var file = file_list[i]
var reader = new FileReader();
reader.onload = function() {
//alert(reader.result);
var txt = reader.result;
console.log("txt: ",txt)
var new_txt = ""
var allTextLines = txt.split(/\r\n|\n/);
for (var j = 0; j<allTextLines.length; j+=1)
{
var res = allTextLines[j].replace("a", "A");
res = res.replace("b", "B");
res = res.replace("c", "C");
res = res.replace("d", "D");
new_txt += res + "\n"
}
console.log("new_txt: ", new_txt)
var new_file = new Blob([new_txt], {type: "text/plain"});
new_file_list.push(new_file); //<---------------------------how do I get this back?
}
reader.readAsText(file);
}
return new_file_list;
}
//watcher
$( "#the-file-field" ).change(function() {
console.log("files have been chosen")
var file_list = this.files
file_list = changeCharsInFiles(file_list)
zipMyFilesAndSave(file_list)
});
} else {
alert('The File APIs are not fully supported in this browser.');
}
答案 0 :(得分:3)
尝试阅读Promise
类,开发它是为了简化异步操作:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
在您的情况下,您可以像这样使用它:
function changeCharsInFiles(file_list){
let promises = [];
for (let file of file_list) {
let filePromise = new Promise(resolve => {
let reader = new FileReader();
reader.readAsText(file);
reader.onload = () => resolve(reader.result);
});
promises.push(filePromise);
}
Promise.all(promises).then(fileContents => {
// fileContents will be an array containing
// the contents of the files, perform the
// character replacements and other transformations
// here as needed
});
}
这只是解决方案的大致轮廓。我建议你首先尝试使用Promise(这可能是一个相当深刻的主题)来弄清楚基本原理,然后应用类似上面的内容。