使用文件对象读取多个文件
Reading multiple files using file object
我正在使用一个文件上传多个文件reader
我的目标是获取每个文件的base64数据作为数组并输出到控制台。但是由于 async
,我的代码总是显示空数组
当所有文件 reader 都被完全读取时,如何显示 base64 数组?
我的代码在这里
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
var file;
var allfiles = [];
function uploadForm() {
Object.keys($('#file')[0].files).forEach(function(f){
reader = new FileReader()
console.log("---------")
reader.readAsDataURL( $('#file')[0].files[f]);
reader.onloadend = function(e) {
allfiles.push(e.target.result);
showMessage("Uploaded")
};
});
console.log(JSON.stringify(allfiles))
showMessage('Uploading file..<img width="20px;" src="https://c.tenor.com/XK37GfbV0g8AAAAi/loading-cargando.gif"/>');
}
/* Object.keys(files).forEach(function(f){
alert(files[f])
reader.readAsDataURL(files[f]);
})*/
function showMessage(e) {
$('#progress').html(e);
$('#file').val('');
}
</script>
<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(); return false;">Upload</button> </td>
</tr>
<tr>
<td colspan="2">
<div id="progress"></div>
</td>
</tr>
</table>
在您的特定情况下,readAsDataURL
在 reader.onloadend
被分配一个侦听器之前完成。重新排序即可解决:
reader.onloadend = function(e) {
allfiles.push(e.target.result);
showMessage("Uploaded")
};
reader.readAsDataURL( $('#file')[0].files[f]);
但这不适用于较大的文件(当 readAsDataURL
行为 async
时)。我建议您开始使用 Promises
:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
var file;
var allfiles = [];
function loadFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
console.log("---------")
reader.onerror = reject;
reader.onload = (e) => resolve(e.target.result);
reader.readAsDataURL(file);
})
}
function filesToArray(files) {
const out = [];
for (let i = 0; i < files.length; ++i) out.push(files[i]);
return out;
}
function uploadForm() {
const files = filesToArray($('#file')[0].files);
let uploaded = 0;
const promises = files.map(async f => {
const result = await loadFile(f);
showMessage(`${uploaded ++}/${files.length}`);
allfiles.push(result);
});
showMessage('Uploading file..<img width="20px;" src="https://c.tenor.com/XK37GfbV0g8AAAAi/loading-cargando.gif"/>');
Promise.all(promises)
.then(r => {
console.log(allfiles);
showMessage('Uploaded');
})
.catch(e => showMessage('Failed'));
}
function showMessage(e) {
$('#progress').html(e);
$('#file').val('');
}
</script>
<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(); return false;">Upload</button> </td>
</tr>
<tr>
<td colspan="2">
<div id="progress"></div>
</td>
</tr>
</table>
我正在使用一个文件上传多个文件reader
我的目标是获取每个文件的base64数据作为数组并输出到控制台。但是由于 async
,我的代码总是显示空数组当所有文件 reader 都被完全读取时,如何显示 base64 数组?
我的代码在这里
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
var file;
var allfiles = [];
function uploadForm() {
Object.keys($('#file')[0].files).forEach(function(f){
reader = new FileReader()
console.log("---------")
reader.readAsDataURL( $('#file')[0].files[f]);
reader.onloadend = function(e) {
allfiles.push(e.target.result);
showMessage("Uploaded")
};
});
console.log(JSON.stringify(allfiles))
showMessage('Uploading file..<img width="20px;" src="https://c.tenor.com/XK37GfbV0g8AAAAi/loading-cargando.gif"/>');
}
/* Object.keys(files).forEach(function(f){
alert(files[f])
reader.readAsDataURL(files[f]);
})*/
function showMessage(e) {
$('#progress').html(e);
$('#file').val('');
}
</script>
<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(); return false;">Upload</button> </td>
</tr>
<tr>
<td colspan="2">
<div id="progress"></div>
</td>
</tr>
</table>
在您的特定情况下,readAsDataURL
在 reader.onloadend
被分配一个侦听器之前完成。重新排序即可解决:
reader.onloadend = function(e) {
allfiles.push(e.target.result);
showMessage("Uploaded")
};
reader.readAsDataURL( $('#file')[0].files[f]);
但这不适用于较大的文件(当 readAsDataURL
行为 async
时)。我建议您开始使用 Promises
:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
var file;
var allfiles = [];
function loadFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader()
console.log("---------")
reader.onerror = reject;
reader.onload = (e) => resolve(e.target.result);
reader.readAsDataURL(file);
})
}
function filesToArray(files) {
const out = [];
for (let i = 0; i < files.length; ++i) out.push(files[i]);
return out;
}
function uploadForm() {
const files = filesToArray($('#file')[0].files);
let uploaded = 0;
const promises = files.map(async f => {
const result = await loadFile(f);
showMessage(`${uploaded ++}/${files.length}`);
allfiles.push(result);
});
showMessage('Uploading file..<img width="20px;" src="https://c.tenor.com/XK37GfbV0g8AAAAi/loading-cargando.gif"/>');
Promise.all(promises)
.then(r => {
console.log(allfiles);
showMessage('Uploaded');
})
.catch(e => showMessage('Failed'));
}
function showMessage(e) {
$('#progress').html(e);
$('#file').val('');
}
</script>
<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(); return false;">Upload</button> </td>
</tr>
<tr>
<td colspan="2">
<div id="progress"></div>
</td>
</tr>
</table>