I'm facing an issue with a file named tst.html
and its content:
part two
(purely for demonstration, no extra markup)
The challenge arises when I try to load this file using synchronous AJAX (XMLHttpRequest
):
function someFunc() {
var str = 'part one_';
var x = new XMLHttpRequest();
x.open('GET', 'tst.html', false); // Using "false" for synchronous request
x.onreadystatechange = function() {
if (x.readyState === 4) {
switch (x.status) {
case 200:
str += x.responseText.trim();
break;
default:
return ''; // Or any desired action
break;
}
}
}
x.send();
str += '_part three';
return str;
}
When calling the above function:
alert(someFunc());
// This will output "part one_part two_part three"
This function performs as expected. However, if I move the AJAX call into a separate function:
function ajaxCall() {
var x = new XMLHttpRequest();
x.open('GET', 'tst.html', false);
x.onreadystatechange = function() {
if (x.readyState === 4) {
switch (x.status) {
case 200:
return x.responseText.trim();
break;
default:
return '';
break;
}
}
}
x.send();
}
function someFunc() {
var str = 'part one';
str += ajaxCall();
str += 'part three';
return str;
}
And then invoke it:
alert(someFunc());
// This time it returns "part one_undefined_part three"
In this scenario, the function returns before the AJAX completes, mirroring the behavior of asynchronous calls.
I've been searching for solutions like a "Synchronous AJAX function," but nothing helpful has turned up so far.
The use case involves the AJAX call within a recursive function set, where further processing depends on the AJAX response. For example:
function one(url) {
var x = new XMLHttpRequest();
x.open('GET', url, false);
x.onreadystatechange = function() {
return two(x.responseText.trim());
}
x.send();
}
function two(str) {
var output;
output += stuff;
// ... parsing through str
// ... until finding a match
if (isURL(match)) {
output += one(match);
} else if (isFormattedString(match)) {
output += two(match);
}
output += more stuff;
// More processing in the output
return output;
}
var final = one(url);
In the provided example:
- the process begins with a URL via
one(url)
one()
outputs a string that's used intwo(str)
- Within
two()
, the parser can encounter either - another URL, or
- a parseable string.
- Based on this, one of the functions is called
- The result is added to the final system output
A callback from one()
won't resolve this issue since I still need a final return
within two()
.
function one(url, callback) {
// ... AJAX operations
{
callback(two(x.responseText));
}
}
function two(str) {
// ... same steps as before
if(isURL(match)) {
one(match, function(result) {
output += result;
// ... additional processing
return output;
});
}else if(...) {
// ... continuing previous logic
}
// ... more actions
}
Another approach could involve using deferred
, yet its application remains uncertain in this context.
Is there a method to enforce JavaScript treating this similarly to other synchronous functions, halting execution until completion? The confusion lies in why this doesn't occur despite declaring the AJAX request as asynchronous.
Thank you for any guidance!