循环上传的文件和 return 一组文件签名
Loop over uploaded files and return an array of file signatures
我想循环选择要上传的文件,获取文件签名和return 一组文件签名。 listOfFileSignatures
数组在 readFirstFourBytes
函数之外是空的。他们是使其在全球范围内可访问的一种方式吗?
var listOfFileSignatures = [];
var totalSize;
var uploadedFiles = document.getElementById("notes").files;
for (file of uploadedFiles) {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
console.log(listOfFileSignatures); // Array(3) [ "ffd8ffdb", "ffd8ffe0", "47494638" ]
};
fileReader.readAsArrayBuffer(blob);
};
console.log(listOfFileSignatures); // Array []
Heres the output
fileReader.onload是异步的,console.log(listOfFileSignatures);在读取文件之前被调用
一个选项是创建一个外部函数,returns一个承诺,返回 listOfFileSignatures 数组
function getListFile() {
return new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
resolve(listOfFileSignatures);
};
}
}
您可以全局声明 listOfFileSignatures,但签名是异步计算的,因此在 for 循环之后列表将直接为空。 FileReader 始终是异步的,因此您无法避免。处理这个问题的一种可能性是检查列表是否在 onloadend (listOfFileSignatures.length == uploadedFiles.length
) 内已满,然后在那里做你想做的事。
更好的方法是使用 promises,如下所示:
var uploadedFiles = document.getElementById("notes").files;
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob);
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});
此外,读取所有字节然后 select 只读取前 4 个字节是低效的。改进版本:
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = new Uint8Array(e.target.result);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob.slice(0, 4));
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});
我想循环选择要上传的文件,获取文件签名和return 一组文件签名。 listOfFileSignatures
数组在 readFirstFourBytes
函数之外是空的。他们是使其在全球范围内可访问的一种方式吗?
var listOfFileSignatures = [];
var totalSize;
var uploadedFiles = document.getElementById("notes").files;
for (file of uploadedFiles) {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
console.log(listOfFileSignatures); // Array(3) [ "ffd8ffdb", "ffd8ffe0", "47494638" ]
};
fileReader.readAsArrayBuffer(blob);
};
console.log(listOfFileSignatures); // Array []
Heres the output
fileReader.onload是异步的,console.log(listOfFileSignatures);在读取文件之前被调用
一个选项是创建一个外部函数,returns一个承诺,返回 listOfFileSignatures 数组
function getListFile() {
return new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
listOfFileSignatures.push(fileSignature);
resolve(listOfFileSignatures);
};
}
}
您可以全局声明 listOfFileSignatures,但签名是异步计算的,因此在 for 循环之后列表将直接为空。 FileReader 始终是异步的,因此您无法避免。处理这个问题的一种可能性是检查列表是否在 onloadend (listOfFileSignatures.length == uploadedFiles.length
) 内已满,然后在那里做你想做的事。
更好的方法是使用 promises,如下所示:
var uploadedFiles = document.getElementById("notes").files;
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = (new Uint8Array(e.target.result)).subarray(0, 4);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob);
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});
此外,读取所有字节然后 select 只读取前 4 个字节是低效的。改进版本:
Promise.all([...uploadedFiles].map(file => new Promise((resolve, reject) => {
var blob = file;
var fileReader = new FileReader();
fileReader.onloadend = function readFirstFourBytes(e) {
var arr = new Uint8Array(e.target.result);
var fileSignature = "";
for (var i = 0; i < arr.length; i++) {
fileSignature += arr[i].toString(16);
};
resolve(fileSignature);
};
fileReader.readAsArrayBuffer(blob.slice(0, 4));
}))).then(function(listOfFileSignatures) {
// this will be called once, when all results are collected.
console.log(listOfFileSignatures);
});