如何使用 Javascript 确保 FileReader 完全读取文件
How to make sure File is read completely by FileReader using Javascript
我在 XML 文件中定义了各种 HTML 元素。
我无法将我的 XML 元素作为一个整体显示,但它有多行,每行都包含复选框、文件上传选项等。
我正在使用 Javascript 获取这些元素,然后使用 XMLHTTPRequest,将这些请求发送到控制器进行处理。
假设 HTML 个元素如下所示:
Row1 ---- Checkbox1_Row1 TextDescription_Row1 FileUpload_Row1
Row2 ---- Checkbox1_Row2 TextDescription_Row2 FileUpload_Row2
我可以有多少行。
使用 Javascript,我得到了所有这些表单元素,这些元素通过行号(Row1,Row2)区分。
我正在遍历每个表单元素然后
for(var j=0; j< formelements.length; j+++)
{
if (formElements[j].type == "textbox")
{
Do something
}
elseif (formElements[j].type == "file")
{
var Base64String;
var ready = false;
var fileName = formElements[j].files[0].name;
var check = function () {
if (ready === true) {
array.push(Base64String);
return;
}
setTimeout(check, 1000);
}
check();
var reader = new FileReader();
reader.onloadend = function (evt) {
Base64String = evt.target.result;
ready = true;
};
reader.readAsDataURL(file);
}
}
我正在使用一个数组来推送与每一行对应的所有值,并且具有最终值的数组将在一些更改后发送到控制器。这里对于文件上传选项,我从每一行读取文件并将它们转换为二进制格式并发送到控制器。如果只有一行,这种方法工作正常。当有多行时,这种方法会发生什么情况,在遍历表单元素时,它会检查第一行(比如文本框)的所有内容并放入数组中,但是当它是文件类型时,它会进入循环并读取文件。在这里读取文件需要一些时间,到时循环会转到下一个表单元素(它只是 Row2)。现在 Row2 表单元素出现并说,我们不上传任何文件,它将为空。现在 check() 函数完成,第 1 行的文件被完全读取。由于循环已经在第 2 行表单元素中,因此除了空值之外,此文件值将分配给第 2 行。因此,就文件类型而言,Row2 将同时具有空值和文件值,但 Row1 没有值。同样,如果我在多行中有许多文件,文件值将根据 FileReader 读取的时间分配给当前循环中存在的任何行形式元素。
我需要确保在移动到下一个表单元素之前完整读取文件值。如何实现?
************************更新******************** **
这里提到的将我的问题标记为重复的问题只有文件类型进来,因此,他们可以遍历文件类型。对我来说,表单元素包括 Checkbox1_Row1、TextDescription_Row1、FileUpload_Row1、Checkbox1_Row2、TextDescription_Row2、FileUpload_Row2.
我必须确保 FileUpload_Row1 在移动到下一个表单元素之前从文件中读取了正确的值,此处 Checkbox1_Row2。
evt
应该是 event
在 evt.target.result
。 .push()
event.target.result
到 fileList
数组,当 fileList
.length
等于 count
时做一些事情
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
var files = Array.prototype.map.call(
document.querySelectorAll("[id^=myFile]")
, function(input) {
return {id:input.dataset.id, file: input.files[0]};
});
var count = files.length; // total number of files
var fileList = []; // accepted files
for (var i = 0; i < count; i++) {
var file = files[i].file;
var id = files[i].id;
var filename = files[i].file.name;
if (i >= count) {
break;
}
var reader = new FileReader();
reader.onload = (function(id, filename) {
return function(event) {
fileList.push({id, filename, file:event.target.result}); {
if (fileList.length === count) {
// do stuff with `fileList`
console.log(fileList);
}
}
}
})(id, filename);
reader.readAsDataURL(file);
}
}
</script>
</head>
<body>
<h1>Hello Plunker!</h1>
<input type="file" id="myFile_row1" data-id="A">
<input type="file" id="myFile_row2" data-id="B">
<input type="file" id="myFile_row3" data-id="C">
<button onclick="myFunction()">Try it</button>
</body>
</html>
我在 XML 文件中定义了各种 HTML 元素。 我无法将我的 XML 元素作为一个整体显示,但它有多行,每行都包含复选框、文件上传选项等。
我正在使用 Javascript 获取这些元素,然后使用 XMLHTTPRequest,将这些请求发送到控制器进行处理。
假设 HTML 个元素如下所示:
Row1 ---- Checkbox1_Row1 TextDescription_Row1 FileUpload_Row1
Row2 ---- Checkbox1_Row2 TextDescription_Row2 FileUpload_Row2
我可以有多少行。
使用 Javascript,我得到了所有这些表单元素,这些元素通过行号(Row1,Row2)区分。
我正在遍历每个表单元素然后
for(var j=0; j< formelements.length; j+++)
{
if (formElements[j].type == "textbox")
{
Do something
}
elseif (formElements[j].type == "file")
{
var Base64String;
var ready = false;
var fileName = formElements[j].files[0].name;
var check = function () {
if (ready === true) {
array.push(Base64String);
return;
}
setTimeout(check, 1000);
}
check();
var reader = new FileReader();
reader.onloadend = function (evt) {
Base64String = evt.target.result;
ready = true;
};
reader.readAsDataURL(file);
}
}
我正在使用一个数组来推送与每一行对应的所有值,并且具有最终值的数组将在一些更改后发送到控制器。这里对于文件上传选项,我从每一行读取文件并将它们转换为二进制格式并发送到控制器。如果只有一行,这种方法工作正常。当有多行时,这种方法会发生什么情况,在遍历表单元素时,它会检查第一行(比如文本框)的所有内容并放入数组中,但是当它是文件类型时,它会进入循环并读取文件。在这里读取文件需要一些时间,到时循环会转到下一个表单元素(它只是 Row2)。现在 Row2 表单元素出现并说,我们不上传任何文件,它将为空。现在 check() 函数完成,第 1 行的文件被完全读取。由于循环已经在第 2 行表单元素中,因此除了空值之外,此文件值将分配给第 2 行。因此,就文件类型而言,Row2 将同时具有空值和文件值,但 Row1 没有值。同样,如果我在多行中有许多文件,文件值将根据 FileReader 读取的时间分配给当前循环中存在的任何行形式元素。
我需要确保在移动到下一个表单元素之前完整读取文件值。如何实现?
************************更新******************** **
这里提到的将我的问题标记为重复的问题只有文件类型进来,因此,他们可以遍历文件类型。对我来说,表单元素包括 Checkbox1_Row1、TextDescription_Row1、FileUpload_Row1、Checkbox1_Row2、TextDescription_Row2、FileUpload_Row2.
我必须确保 FileUpload_Row1 在移动到下一个表单元素之前从文件中读取了正确的值,此处 Checkbox1_Row2。
evt
应该是 event
在 evt.target.result
。 .push()
event.target.result
到 fileList
数组,当 fileList
.length
等于 count
<!DOCTYPE html>
<html>
<head>
<script>
function myFunction() {
var files = Array.prototype.map.call(
document.querySelectorAll("[id^=myFile]")
, function(input) {
return {id:input.dataset.id, file: input.files[0]};
});
var count = files.length; // total number of files
var fileList = []; // accepted files
for (var i = 0; i < count; i++) {
var file = files[i].file;
var id = files[i].id;
var filename = files[i].file.name;
if (i >= count) {
break;
}
var reader = new FileReader();
reader.onload = (function(id, filename) {
return function(event) {
fileList.push({id, filename, file:event.target.result}); {
if (fileList.length === count) {
// do stuff with `fileList`
console.log(fileList);
}
}
}
})(id, filename);
reader.readAsDataURL(file);
}
}
</script>
</head>
<body>
<h1>Hello Plunker!</h1>
<input type="file" id="myFile_row1" data-id="A">
<input type="file" id="myFile_row2" data-id="B">
<input type="file" id="myFile_row3" data-id="C">
<button onclick="myFunction()">Try it</button>
</body>
</html>