I have an old function that is no longer functional. According to the console window, synchronous mode is no longer permitted for use. How would I convert this to use asynchronous mode and deliver the data out?
var loadfile = function (filename, filetype) // Reads a file and returns it's contents as a string.
{filetype = filetype || 'text' // Assume text if no filetype is passed in
var reader = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP"); // Provide a fallback for IE
reader.responseType = filetype; // Prepare to read the proper type of data
reader.open("GET", filename, false); // Target our local filename and prepare for synchronous read
reader.send(); // Begin the read
return reader.responseText; // Return the data as expected
};
I know I could force this to operate by removing line 4, but then I get XML Errors and warnings about the depreciated synchronous mode being employed. Warnings that could become 'no longer supported' errors that would block the program run months from now.
Also, I can switch to asynchronous mode by changing line 5's false to true, but then there's no data being passed out as the last line is invoked immediately. I could involve reader.onloadend() to process the data, but a return invoked there just casts the read data into the void when I need it to be passed back to the caller of loadfile().
Ergo, I'm stuck. What am I missing here?
EDIT: Adding a potential async version here and pointing out how it doesn't work.
var loadfile = function (filename, filetype)
{var output = '';
filetype = filetype || 'text';
var reader = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
reader.responseType = 'text';
reader.open('GET', filename);
reader.onloadend = function () {output = reader.responseText;}
reader.send();
while (output === '') {}
return output;
};
Naturally this has several issues. First, the scope of reader.onloadend() makes it's copy of output separate from the one in loadfile(). So the retrieved data just disappears. We could return it instead of assigning it to a local variable, but onloadend fires itself (as events do) and the returned data is sent into the void. Unrecoverable. Second, even if we could change loadfile()'s version of output from within the onloadend() function as per passing by reference in C++, the while loop that waits for the output variable to change would (because JavaScript is a single process thread) lock up the system, running an infinite loop and not allowing any changes to occur.
Ergo, still stuck. Yes, we could output to window.name or console.log or document.write, but none of these options allows loadfile() to return the data acquired from XHMLHttpRequest/filename.
At this point I'm stuck with the depreciated synchronous xhr, and XML Parsing Errors as I am retrieving raw text, not XML.
EDIT SECUNDUS: I finessed the script to default to synchronous mode, and managed to silence the errors (but not the initial warning about using a depreciated method...thankfully that doesn't spam warnings on every usage). Needless to say using async/true on this function will not get you anywhere, but async/false does work....for now. Sharing in case anyone else needs this particular functionality.
var loadfile = function (filename, async)
{if ("undefined" === typeof(async)) {async = false;}
var reader = new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP");
reader.open('GET', filename, async);
reader.onloadend = function () {return reader.responseText;}; // Lost to /dev/null while the program executes without this data. Unacceptable!
reader.overrideMimeType('text/plain');
try
{reader.send();}
catch (e)
{return null;}
if (!async) {return reader.responseText;}
//TODO: Find some way to delay execution without generating an infinite loop (good luck - javascript is not multithreaded so we cannot use a while loop for this)
//TODO: Extract reader.responseText from within reader.onloadend() (probably by invoking a global temp object to shift the data out of onloadend()).
};