【问题标题】:Reading multiple files using file object使用文件对象读取多个文件
【发布时间】:2021-11-20 10:48:34
【问题描述】:

我正在使用文件阅读器上传多个文件

我的目标是将每个文件的 base64 数据作为数组并输出到控制台。但是由于异步,我的代码总是显示空数组

当所有文件读取器都被完全读取后,如何显示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>&emsp;</td>
        </tr>
        <tr>
            <td colspan="2">
                <div id="progress"></div>
            </td>
        </tr>
    </table>
    

【问题讨论】:

标签: javascript html jquery file filereader


【解决方案1】:

在您的具体情况下,readAsDataURLreader.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>&emsp;</td>
    </tr>
    <tr>
        <td colspan="2">
            <div id="progress"></div>
        </td>
    </tr>
</table>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    相关资源
    最近更新 更多