HTML5 FileReader как вернуть результат?

Я использую JS FileReader. Я хочу получить результат после операции чтения файла и работать с этими данными. FileReader работает асинхронно, и я не знаю, когда будет готов результат. Как это сделать правильно?

$(document).ready(function(){
    $('#file_input').on('change', function(e){
        var res = readFile(this.files[0]);

        //my some manipulate with res

        $('#output_field').text(res);
    });
});

function readFile(file){
    var reader = new FileReader(),
        result = 'empty';

    reader.onload = function(e)
    {
        result = e.target.result;
    };

    reader.readAsText(file);

    //waiting until result is empty?

    return result;
}

http://jsfiddle.net/ub22m/4/

Это шоу «пустое».

Как дождаться, пока "результат" не станет пустым? По-другому?


person trafalgarx    schedule 06.08.2012    source источник


Ответы (4)


Чтение происходит асинхронно. Вам необходимо предоставить собственный обратный вызов onload, который определяет, что должно произойти после завершения чтения:

$(document).ready(function(){
    $('#file_input').on('change', function(e){
        readFile(this.files[0], function(e) {
            // use result in callback...
            $('#output_field').text(e.target.result);
        });
    });
});

function readFile(file, onLoadCallback){
    var reader = new FileReader();
    reader.onload = onLoadCallback;
    reader.readAsText(file);
}

(См. Fiddle.)

Обратите внимание, что readFile не возвращает значения. Вместо этого он принимает функцию обратного вызова, которая срабатывает всякий раз, когда выполняется чтение. Операция $('#output_field').text перенесена в функцию обратного вызова. Это гарантирует, что эта операция не будет запущена до тех пор, пока не сработает обратный вызов onload читателя, когда e.target.result не будет заполнен.

Программирование с обратными вызовами поначалу немного сложно сделать правильно, но оно абсолютно необходимо для реализации расширенной функциональности.

person apsillers    schedule 06.08.2012
comment
Есть ли разница между двумя e? - person Chris Chudzicki; 22.05.2015
comment
@ChrisChudzicki Да, они разные. Первый e - это объект события jQuery. Второй e - это объект события загрузки. - person trafalgarx; 19.10.2016

Используйте Promise, чтобы обернуть FileReader, а затем использовать await для получения результатов:

https://blog.shovonhasan.com/using-promises-with-filereader/

person Aymon Fournier    schedule 27.04.2018

Вот javascript:

$(document).ready(function() {
    $('#file_input').on('change', function(e) {

        function updateProgress(evt) {
            if (evt.lengthComputable) {
                // evt.loaded and evt.total are ProgressEvent properties
                var loaded = (evt.loaded / evt.total);
                if (loaded < 1) {
                    // Increase the prog bar length
                    style.width = (loaded * 200) + "px";
                }
            }
        }

        function loaded(evt) {
            // Obtain the read file data    
            var fileString = evt.target.result;
            // Handle UTF-16 file dump
            $('#output_field').text(fileString);
        }
        var res = readFile(this.files[0]);

        var reader = new FileReader();

        reader.readAsText(this.files[0], "UTF-8");

        reader.onprogress = updateProgress;
        reader.onload = loaded;


    });
});

function readFile(file) {
    var reader = new FileReader(),
        result = 'empty';

    reader.onload = function(e) {
        result = e.target.result;
    };

    reader.readAsText(file);

    return result;
}

И, конечно же, часть HTML:

<input type="file" id="file_input" class="foo" />
<div id="progBar" style="background-color:black;width:1px;"> </div>
<div id="output_field" class="foo"></div>

Кажется, работает для файлов * .txt.

См. эту скрипку.

person Community    schedule 06.08.2012
comment
странно, скрипка вернулась к старой версии. Исправлено сейчас. - person ; 06.08.2012
comment
return - это ключевое слово, которое, как мне кажется, здесь упоминалось. Функция readFile всегда будет возвращать пустое значение. - person Urasquirrel; 17.05.2016

вариант использования FileReader

<html>
    <head>
        <link rel="stylesheet" href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
        <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>
    </head>
    <body>
        <script>
            function PreviewImage() {
            var oFReader = new FileReader();
            oFReader.readAsDataURL(document.getElementById("uploadImage").files[0]);
            oFReader.onload = function (oFREvent) {
                var sizef = document.getElementById('uploadImage').files[0].size;
                document.getElementById("uploadPreview").src = oFREvent.target.result;
                document.getElementById("uploadImageValue").value = oFREvent.target.result; 
            };
        };
        jQuery(document).ready(function(){
            $('#viewSource').click(function ()
            {
                var imgUrl = $('#uploadImageValue').val();
                alert(imgUrl);
            });
        });
        </script>
        <div>
            <input type="hidden" id="uploadImageValue" name="uploadImageValue" value="" />
            <img id="uploadPreview" style="width: 150px; height: 150px;" /><br />
            <input id="uploadImage" style="width:120px" type="file" size="10" accept="image/jpeg,image/gif, image/png" name="myPhoto" onchange="PreviewImage();" />
        </div>
        <a href="#" id="viewSource">Source file</a>
    </body>
</html>
person websky    schedule 19.02.2015