Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 循环上传的文件并返回文件签名数组_Javascript_Arrays_Fileapi - Fatal编程技术网

Javascript 循环上传的文件并返回文件签名数组

Javascript 循环上传的文件并返回文件签名数组,javascript,arrays,fileapi,Javascript,Arrays,Fileapi,我想循环选择要上载的文件,获取文件签名并返回一组文件签名。listOfFileSignatures数组在readFirstFourBytes函数外为空。这是一种让全球都能访问的方式吗 var listOfFileSignatures = []; var totalSize; var uploadedFiles = document.getElementById("notes").files; for (file of uploadedFiles) { var blob

我想循环选择要上载的文件,获取文件签名并返回一组文件签名。
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 [] 
var listOfFileSignatures=[];
var总大小;
var uploadedFiles=document.getElementById(“notes”).files;
对于(上载文件的文件){
var blob=文件;
var fileReader=newfilereader();
fileReader.onloadend=函数readFirstFourBytes(e){
var arr=(新的Uint8Array(e.target.result)).子数组(0,4);
var fileSignature=“”;
对于(变量i=0;i

fileReader.onload是异步的,console.log(ListOfficeSignatures);在读取文件之前调用

一个选项是创建一个返回承诺的外部函数,返回ListOfficeSignatures数组

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);
        };
    }
}
函数getListFile(){ 返回新承诺((解决,拒绝)=>{ var blob=文件; var fileReader=newfilereader(); fileReader.onloadend=函数readFirstFourBytes(e){ var arr=(新的Uint8Array(e.target.result)).子数组(0,4); var fileSignature=“”; 对于(变量i=0;i
您可以全局声明ListOfficeSignatures,但签名是异步计算的,因此在for循环之后,列表将直接为空。FileReader始终是异步的,因此您无法避免这种情况。处理这种情况的一种可能性是检查onloadend中的列表是否已满(
listOfFileSignatures.length==uploadedFiles.length
)然后在那里执行您想要的操作

更好的方法是使用承诺,如下所示:

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);
});
var uploadedFiles=document.getElementById(“notes”).files;
Promise.all([…uploadedFiles].map(文件=>newpromise((解析,拒绝)=>{
var blob=文件;
var fileReader=newfilereader();
fileReader.onloadend=函数readFirstFourBytes(e){
var arr=(新的Uint8Array(e.target.result)).子数组(0,4);
var fileSignature=“”;
对于(变量i=0;i
此外,读取所有字节,然后仅选择前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);
});
Promise.all([…uploadedFiles].map(文件=>newpromise((解析,拒绝)=>{
var blob=文件;
var fileReader=newfilereader();
fileReader.onloadend=函数readFirstFourBytes(e){
var arr=新的Uint8Array(即target.result);
var fileSignature=“”;
对于(变量i=0;i
您没有在任何地方声明
listOfFileSignatures
。在
for
循环之前,只需添加
listOfFileSignatures=[];
全局声明,只需将
const listOfFileSignatures=[]
放在
for(文件…
行之前。@imvain2我有
var listOfFileSignatures=[]
在for循环之前。@Terrymose在fore循环之前我已经有了一个
ListofLessignatures
,我已经编辑了代码示例。@simanacci,因为您已经声明了它,这意味着问题只是在所有
onloadend
调用完成之前运行了控制台。这意味着您需要运行回调函数,该函数使用列表中最后一个文件的onloadend中的
listOfFileSignatures