-1

Following is my piece of code which read file from the path specified

for (var i in e.target.files) {
    var reader = new FileReader();
    reader.onload = function (e) {
        alert("File loaded successfully");
        var output = e.target.result;
        //             console.log("output: "+output);
    }

reader.log is asyncronous function what i want is to wait until reader.load event is fired then move to next iteration.

I also forcefully stop this by infinite for loop but my browser crashes on this. i have also tries settimeout and setinterval method but all in vain. i just to stop until reader.load event is fires and then move to next iteration.

Qantas 94 Heavy
  • 15,750
  • 31
  • 68
  • 83
Muneem Habib
  • 1,046
  • 4
  • 18
  • 49
  • 2
    You don't want to "wait" in JS, ever. – ThiefMaster Nov 29 '13 at 12:27
  • And even _if_ you wanted to, erase the thought from your mind (i.e. it's impossible). – Qantas 94 Heavy Nov 29 '13 at 12:28
  • Most likely you want to pass a callback function somewhere in which you put the logic for after the file is loaded. – Bart Enkelaar Nov 29 '13 at 12:29
  • 1
    See [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call). It applies to your situation as well. – Felix Kling Nov 29 '13 at 12:30
  • 1
    Well, you can use continuations to accomplish basically what you are trying to do. it's not exactly easy in javascript, but... http://matt.might.net/articles/by-example-continuation-passing-style/ It may be a bit mind boggling at first, but it allows you to work properly in an asynchronous environment. – Luaan Nov 29 '13 at 12:30
  • sir i can do it through webwroker but i am thinking of other way to wait for sometime – Muneem Habib Nov 29 '13 at 12:30
  • **There is absolutely no way, I am telling you right now.** – Qantas 94 Heavy Nov 29 '13 at 12:35

3 Answers3

1

JavaScript is built to be asynchronous. If low-level developer decided that some function need to be async, there is nothing you can do, and you should not, actually. Probably, it can take some time, and user will see his browser (or other runtime environment) hanged.

Tommi
  • 3,199
  • 1
  • 24
  • 38
0

You should restructure the code, so you don't wait, but fire a callback for each asynchronous event, that would increment a counter, and do the function again. Something like:

var files = [],
    fileCount = 0,
    currentFile = 0;
for (var i in e.target.files) {
  if (e.target.files.hasOwnProperty(i)) {
    fileCount++;
  }
}

function allLoaded() {
  // process data.
}

function loadHandler(loadEvent) {
  files.push(loadEvent.target);
  loadNext();
}

(function loadNext() {
  if (currentFile < fileCount) {
    currentFile++;
    var reader = new FileReader();
    reader.onload = loadHandler;
  } else {
    allLoaded();
  }
})();
Poetro
  • 574
  • 3
  • 9
  • And what is the issue with it being called asynchronously? It is how JavaScript work, and you should not even think about changing it. If you'd like to notify the user about the progress you can do that, but don't try to hang the browser, as they usually do not tolerate that, and close the tab, and never come back. – Poetro Nov 29 '13 at 13:34
0

Assuming your code snippet is missing a call similar to reader.log(i) the solution is as follows:

var currentItemIndex = 0;

if (e.target.files.length > currentItemIndex) {
    readNext(e.target.files[currentItemIndex]);
}
else {
    endOfWait();
}

function readNext(item) {

    currentItemIndex ++;

    var reader = new FileReader();
    reader.onload = function (x) {
        alert("File loaded successfully");
        var output = x.target.result;

        if (e.target.files.length > currentItemIndex) {        
            readNext(e.target.files[currentItemIndex]);
        }
        else {
            endOfWait();
        }
    }

    reader.log(item);
}

function endOfWait() {
    // put code here that executes once the wait is over
}
SilverlightFox
  • 32,436
  • 11
  • 76
  • 145