我有一个文件tst.html
,内容为:
part two
(没有标记或其他任何内容,只是为了演示)
然后通过 同步 AJAX(XMLHttpRequest
)加载所述文件:
function someFunc() {
var str = 'part one_';
var x = new XMLHttpRequest();
x.open('GET', 'tst.html', false); // "false" for synchronous
x.onreadystatechange = function() {
if(x.readyState === 4) {
switch(x.status) {
case 200:
str += x.responseText.trim();
break;
default:
return ''; // Or something
break;
}
}
}
x.send();
str += '_part three';
return str;
}
调用该函数:
alert(someFunc());
// Returns "part one_part two_part three"
这是所需的行为。
但是如果我把AJAX调用放到它自己的函数中:
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);
在上面的示例中:
one(url)
)one()
返回一个字符串,它本身就是two(str)
在two()
内,解析器可以遇到
另一个网址,或
一个可解析的字符串。
根据它的不同,两个函数之一称为
来自one()
的回调也不会对此产生影响,因为我仍然需要在return
内设置最终two()
。
function one(url, callback) {
// ... AJAX stuff
{
callback(two(x.responseText));
}
}
function two(str) {
// ... same as previous
// The following doesn't work, because then `two()` no longer has a `return`
// ... and any other code (i.e. for !isURL cases) will still continue to execute
if(isURL(match)) {
one(match, function(result) {
output += result;
// ... more processing
return output;
});
}else if(...) {
// ... same as previous
}
// ... more stuffs
}
我发现的唯一另一件事是deferred
,但我不确定它是如何运作的。
有没有办法强制JavaScript像其他同步函数一样处理它,执行代码会停止,直到函数完成?我不清楚它为什么还没有,因为AJAX请求被特别声明为异步。
提前致谢。
答案 0 :(得分:6)
我喜欢你冗长而详细的问题(希望每个人都尽可能多地投入询问!),但实质上它归结为:
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!了解异步函数的工作方式,尤其是How do I return the response from an asynchronous call?
答案 1 :(得分:1)
问题在于您的val3
return
从处理程序返回,但不是从return x.responseText.trim();
函数返回 - 它没有ajaxCall
语句,所以总是返回return
。