Getting the result object of FileReader()

2019-03-07 06:22发布

问题:

is there any way i can fetch the result object of a FileReader() without getting through a function ?

i have made a sample code below:

HTML

<br /> <br /> <br />

<div>

</div>

JS

var code = "lorem ipsum";

$("input[type='file']").change(function() {
    var upload = this.files[0];

    var reader = new FileReader();
    reader.onload = function() {
        code = reader.result;
        $("div").append("<label>this should appear first: " + code + "</label> <br />");
    };
    reader.readAsDataURL(upload);

    $("div").append("<label> this should appear last: " + code + "</label> <br />");
});

the problem with this code is that the reader.onload = ... line is skipped and is run right after the last line of the script. not the usual top to bottom reading of a code. and so, when this code is run, you will receive an exact result as below:

this should appear last: asd 
this should appear first: data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QC+...

notice that this should appear last appears first before this should appear first.

whereas as if according to the script if it is read from top to bottom, this should appear first must appear before this should appear last.

this is where i apply my conclusion that the reader.onload... line is skipped all throughout and is run before the script ends.

this is where my dilemma begins, i need to find an alternative code where i don't have to use a function on reader.onload. simply assigning reader.onload = reader.result does not work.

with this current code, the first run of the script returns code as lorem ipsum and on the second run returns data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QC+.... but i need code to be data:image/jpeg;base64,/9j/4AAQSkZJRgABAgAAAQABAAD/7QC+... right after the script is executed on its first time.

sorry for my confusing explanation. i am not very fond of expressing myself in english since it is not my native language. thank you

回答1:

is there any way i can fetch the result object of a FileReader() without getting through a function ?

No. FileReader() is asynchronous. You can use Promise to achieve expected result

var code = "lorem ipsum";

    $("input[type='file']").change(function() {
      var upload = this.files[0];
      var p = new Promise(function(resolve) {
        var reader = new FileReader();
        reader.onload = function() {
          code = reader.result;
          // pass `div` as resolve `Promise` to `.then()`
          resolve($("div").append("<label>this should appear first: " 
                                  + code + "</label> <br />"));
        };
        reader.readAsDataURL(upload);
      });
      p.then(function(elem) {
        elem.append("<label> this should appear last: " 
                    + code + "</label> <br />");
      })

    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input type="file" />
<div></div>



回答2:

The FileReader is asynchronous, so logic execution continues on past the load event handler while it waits for the file to be read. This means that (as with any async handler) all code reliant on the async event must be placed within the event handler. Try this:

var reader = new FileReader();
reader.onload = function() {
    code = reader.result;
    $("div").append("<label>this should appear first: " + code + "</label> <br />");
    $("div").append("<label> this should appear last: " + code + "</label> <br />");
};
reader.readAsDataURL(upload);