<input type="file" onchange="readFile(this)">
<script>
function readFile(input) {
let file = input.files[0];
let reader = new FileReader();
reader.readAsText(file);
reader.onload = function() {
console.log(reader.result);
reader.onerror = function() {
console.log(reader.error);
</script>
this works greatly but i do not get the asynch nature of it as i am aware that onLoad is sort of addeventListener which will be running in the browser APIs so when the load change occurs it will fire the callback function .
But what about reader.readAsText(file)?
My guess is it is reading the file asynchronously but if it is reading file in an Async manner why is there no callBack function attached to it which will run after it completes reading the file , as seen in the fs modules fileread() function where we have a specific callback to know that now file reading is complete or failed.
So please help me understand how reader.readAsText(file) this is async and whether it is async or not or it is just i am confusing two different scenarios completely altogther.
–
If you review the 'Event handlers' section of this API's MDN docs, you'll see that there are more than just the onload
and onerror
events that you could handle, such as onprogress
. If the readAsText
method took a callback argument, how would that one callback handle all of those potential events? When should that callback be invoked? Would that callback be invoked more than once?
–
This days FileReader have very little benefits now when we have new read methods on the blob (you would only need it for IE - which is mostly dead now)
If you are going to read binary (excel) files (and no ascii text files), then you can't read the content as text, b/c some encoding transformation will take place and make the string invalid, so you should actually read it as arrayBuffer
a modern approach that is asynchronous but feels synchronous would look something like this:
async function readFile (input) {
const [file] = input.files
if (!file) return // in case input have been cleared
const buffer = await file.arrayBuffer()
const uint8 = new Uint8Array(a)
(less code, no callbacks, and still async)
(using the new read on blobs is preferred since it adds wider platform support on both Deno and NodeJS servers)
–
reader.readAsText(file)
is something that is a synchronous code execution
So code after readAsText
will actually run before reader.onload
is being called
readAsText
will just start another code execution and call some other function when something else happens
It's just structured in another way internally, instead of using a traditional callback function you have to register the function that you are interested for on some class instance. The FileReader has multiple "callback" functions (aka: eventlistener) that can be invoked after a delay and you don't need add a EventListener to all of them
onabort: (...)
onerror: (...)
onload: (...)
onloadend: (...)
onloadstart: (...)
onprogress: (...)
if you only need one or two of them (say: onload and onprogress) then it would be unnecessary to have to do apply arguments for each one of them: readAsText(file, ...noopFn, loadCallback, ...noopFn, progressCallback)
It's the same thing with old XMLHttpRequest
ajax method
you don't add a callback when it returns the response you can listen for abortion, error, timeout, download & upload progress, state changed (when request have been open & sent, receive response header & body)
Just b/c it dose not have a callback function dosen't mean that something is async or sync. It's the delay that defines something as async
I mean [].forEach(callbackFn)
has a callback function and it isn't async
So those setTimeout(callbackFn, 1000)
but this is async
The part of what makes some function logic async is when a other function is being executed/or continued (in case of iterators & generators)... the question is: is it called immediately or after some delay? The readAsText
is synchronous but the "logic" of getting the file content is asynchronous
in other words if some function is not executed on the same call stack then it's considered as async
Dose this make since?
Oh and one more thing a FileReader instance can be reused more than once, so that you don't have to decleare the same error/callback functions again and again
All doe you can't use it simultanas if it's already reading something.
That is also one part of the reason why there isn't any callback arguments in the readAsText
–
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.