我有一个文件,tst.html
与内容:JavaScript(Vanilla,no jQuery) - 具有* synchronous的函数* AJAX(XMLHttpRequest)调用的行为与async相同?
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;
}
调用好玩ction:
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);
在上面的例子:
- 系统总是与URL启动(
one(url)
) one()
返回一个字符串,其本身为two(str)
开口参数
在
two()
内,解析器可能遇到以下任一种:另一个URL或
一个可解析的字符串。
取决于哪个是,两个功能中的一个被称为
- 的输出被添加到系统中的最终结果
one()
从一个回调将不起作用在这一点上,因为我仍然需要在two()
之内有最后的return
。
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请求特别声明为异步。
在此先感谢。
你的函数'ajaxCall'不返回任何东西 - 相当于'return undefined' - 你需要从函数返回一些东西(不是onreadystate回调) –
同步ajax调用真的不是一个好主意 - 如果服务器有问题会怎样? JavaScript线程将等待直到服务器响应,并且页面将完全不响应用户。同步ajax永远不会有好的例子。不要使用它。 – Simba
我会建议尝试使用“承诺”(整洁的东西)。在Jamiec的回答中发布的链接中给出了一个简要的解释,否则在MDN中查看:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise – Winter