JavaScript(普通的,没有jQuery)-带有*synchronous*AJAX(XMLHttpRequest)调用的函数的行为与异步相同?
我有一个文件,JavaScript(普通的,没有jQuery)-带有*synchronous*AJAX(XMLHttpRequest)调用的函数的行为与异步相同?,javascript,ajax,synchronous,Javascript,Ajax,Synchronous,我有一个文件,tst.html,内容如下: part two (无标记或任何其他内容,仅用于演示) 然后通过synchronousAJAX(XMLHttpRequest)加载所述文件: 调用函数: alert(someFunc()); // Returns "part one_part two_part three" function ajaxCall() { var x = new XMLHttpRequest(); x.open('GET', 'tst.html', f
tst.html
,内容如下:
part two
(无标记或任何其他内容,仅用于演示)
然后通过synchronousAJAX(XMLHttpRequest
)加载所述文件:
调用函数:
alert(someFunc());
// Returns "part one_part two_part three"
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;
}
这是理想的行为
但是如果我将AJAX调用放入它自己的函数中:
alert(someFunc());
// Returns "part one_part two_part three"
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;
}
然后称之为:
alert(someFunc());
// Returns "part one_undefined_part three"
该函数在AJAX有机会完成之前返回合并的字符串,这与其异步函数的行为相同
我一直在寻找类似“同步AJAX函数”的东西,但没有发现任何有用的东西
AJAX调用的最后一个用例是在一组递归函数中,进一步的处理依赖于AJAX返回。比如:
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;
// ... parse through str
// ... until match found
if(isURL(match)) { // If `match` is a URL
output += one(match);
}else if(isFormattedString(match)) { // if `match` is a string
output += two(match);
}
output += more stuff;
// More processing of output
return output;
}
var final = one(url);
在上述示例中:
- 系统始终使用URL启动(
)one(URL)
返回一个字符串,该字符串本身就是one()
two(str)
- 在
two()
- 另一个URL,或
- 可解析的字符串
- 根据它是哪个函数,调用两个函数中的一个
- 输出被添加到系统的最终结果中
one()
的回调对此也不起作用,因为我仍然需要在two()
中有一个最终的返回值
我唯一发现的另一件事是,但我也不确定它将如何与此配合使用
有没有办法强迫JavaScript像对待其他同步函数一样对待这个问题,在同步函数中,执行代码会停止,直到函数完成?我不清楚为什么它还没有,因为AJAX请求被明确声明为异步的
提前感谢。问题是您的返回了
return x.responseText.trim();
从处理程序返回,但不是从ajaxCall
函数返回-它没有return
语句,因此总是返回未定义的我喜欢你冗长、详细的问题(希望每个人都尽可能多地提问!),但本质上它归结为:
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();
}
您的return
语句是从onreadystatechange
返回的,而不是您预期的ajaxCall
。它与原来的不同之处在于,原来的只是串接字符串。它与将其移动到自己的功能无关
不要使用同步ajax!了解异步函数是如何工作的,特别是你的函数ajaxCall
不返回任何东西-这相当于返回未定义的-你需要从函数返回一些东西(不是onreadystate回调)。同步ajax调用真的不是一个好主意-如果服务器有问题怎么办?JavaScript线程只会等待服务器响应,因此页面将对用户完全没有响应。同步ajax从来都不是一个好的例子。不要使用它。我建议尝试使用“承诺”(整洁的东西)。Jamiec答案中的链接给出了简要说明,否则请在MDN上查看: