Estoy leyendo los datos del archivo como cadena de datos junto con el nombre del archivo
Mi código dará como resultado un nombre de archivo correcto, pero los datos del archivo se muestran vacíos {}
La salida esperada es
[{ filename: "name1.txt", filedata: "data:text/plain;base64,VGhpc.." }, { filename: "name2.txt", filedata: "data:text/plain;base64,VGhpc.." }]mi codigo es
function readFile(file) { return new Promise(function(resolve, reject) { let fr = new FileReader(); fr.onload = function() { resolve(fr.result); }; fr.onerror = function() { reject(fr); }; fr.readAsDataURL(file) }); } // Handle multiple fileuploads function uploadForm() { let files = $('#file')[0].files // ev.currentTarget.files; let readers = []; if (!files.length) return; for (let i = 0; i < files.length; i++) { readers.push({ "filedata": readFile(files[i]), "filename": files[i].name }); } Promise.all(readers).then((values) => { console.log(JSON.stringify(values)); return }); } function showMessage(e) { $('#progress').html(e); $('#file').val(''); } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <body> <table cellpadding="5px"> <tr> <td>Select File:</td> <td> <input id="file" type="file" value="" accept=".csv,.xlsx,.docx,.rtf,.pdf,.pptx,.txt" multiple> </td> </tr> <tr> <td colspan="2"><button onclick="uploadForm();" id="upload">Upload</button> </td> </tr> <tr> <td colspan="2"> <div id="progress"></div> </td> </tr> </table> </body> </html>Repararía esto simplemente colocando las promesas en una matriz, para que pueda esperarlas fácilmente con Promise.all . Luego, cuando obtenga su matriz de resultados, asígnela a una matriz de { filedata, filename } .
Aquí está la parte diferente:
for (let i = 0; i < files.length; i++) { readers.push(readFile(files[i])); } Promise.all(readers).then((values) => { const result = values.map((filedata,i) => ({ filedata, filename: files[i].name })); console.log(JSON.stringify(result)); return }); function readFile(file) { return new Promise(function(resolve, reject) { let fr = new FileReader(); fr.onload = function() { resolve(fr.result); }; fr.onerror = function() { reject(fr); }; fr.readAsDataURL(file) }); } // Handle multiple fileuploads function uploadForm() { let files = $('#file')[0].files // ev.currentTarget.files; let readers = []; if (!files.length) return; for (let i = 0; i < files.length; i++) { readers.push(readFile(files[i])); } Promise.all(readers).then((values) => { const result = values.map((filedata,i) => ({ filedata, filename: files[i].name })); console.log(JSON.stringify(result)); return }); } function showMessage(e) { $('#progress').html(e); $('#file').val(''); } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <body> <table cellpadding="5px"> <tr> <td>Select File:</td> <td> <input id="file" type="file" value="" accept=".csv,.xlsx,.docx,.rtf,.pdf,.pptx,.txt" multiple> </td> </tr> <tr> <td colspan="2"><button onclick="uploadForm();" id="upload">Upload</button> </td> </tr> <tr> <td colspan="2"> <div id="progress"></div> </td> </tr> </table> </body> </html>El argumento de Promise.all() debe ser una matriz de promesas. readers es una matriz de objetos ordinarios, las promesas están en las propiedades de los datos del filedata . Solo está registrando esos objetos, no el resultado de las promesas.
Extraiga las propiedades de los datos del filedata cuando llame a Promise.all() .
Luego, en la devolución de llamada de Promise.all() , puede recorrer todos los resultados y registrarlos junto con el nombre de archivo correspondiente de los readers .
function readFile(file) { return new Promise(function(resolve, reject) { let fr = new FileReader(); fr.onload = function() { resolve(fr.result); }; fr.onerror = function() { reject(fr); }; fr.readAsDataURL(file) }); } // Handle multiple fileuploads function uploadForm() { let files = $('#file')[0].files // ev.currentTarget.files; let readers = []; if (!files.length) return; for (let i = 0; i < files.length; i++) { readers.push({ "filedata": readFile(files[i]), "filename": files[i].name }); } Promise.all(readers.map(r => r.filedata)).then((values) => { values.forEach((value, i) => console.log(readers[i].filename, JSON.stringify(value))) }); } function showMessage(e) { $('#progress').html(e); $('#file').val(''); } <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <body> <table cellpadding="5px"> <tr> <td>Select File:</td> <td> <input id="file" type="file" value="" accept=".csv,.xlsx,.docx,.rtf,.pdf,.pptx,.txt" multiple> </td> </tr> <tr> <td colspan="2"><button onclick="uploadForm();" id="upload">Upload</button> </td> </tr> <tr> <td colspan="2"> <div id="progress"></div> </td> </tr> </table> </body> </html>