Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript(普通的,没有jQuery)-带有*synchronous*AJAX(XMLHttpRequest)调用的函数的行为与异步相同?_Javascript_Ajax_Synchronous - Fatal编程技术网

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上查看: