当前位置: 首页 > 知识库问答 >
问题:

JavaScript(普通的,没有jQuery)-带有*synchronous*AJAX(XMLHttpRequest)调用的函数的行为与异步相同?

倪鸿禧
2023-03-14

我有一个文件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()的回调对此也不起作用,因为我仍然需要在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
}

有没有办法强迫JavaScript像对待其他同步函数一样对待这个问题,在同步函数中,执行代码会停止,直到函数完成?我不清楚为什么它还没有,因为AJAX请求被明确声明为异步的。


共有2个答案

明正德
2023-03-14

问题是您的返回

return x.responseText.trim();

从处理程序返回,但不是从ajaxCall函数返回-它没有return语句,因此总是返回undefined

晁砚
2023-03-14

我喜欢你提出的冗长而详细的问题(希望每个人都尽可能多地提问!),但本质上可以归结为:

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!了解异步函数如何工作,特别是如何从异步调用返回响应?

 类似资料:
  • 问题内容: 我正在编写一个通用函数,该脚本将在脚本的多个位置重用。 该函数使用ajax(使用jQuery库),所以我想以某种方式将一个函数(或代码行)传递给该函数以在ajax完成时执行。我相信这应该是一个回调函数,但是在阅读了一些回调答案之后,我仍然对如何实现这种情况感到困惑。 我当前的功能是: 有了这个功能,我希望能够以与其他jQuery功能相同的方式来做某事,即: 问题答案: 只需为函数提供另

  • 问题内容: 我不太了解如何使用jQuery的ajax函数的回调。 我在JavaScript中有以下代码: 在服务器端(AppEngine / Python),我获取了回调参数的值并使用 但是随后我在浏览器控制台中看到了。 处理此问题的正确方法是什么?现在,我得到了所需的结果,但是我知道这不正确的事实困扰着我。 问题答案: 这就是我在我身上所做的

  • 问题内容: 在这里,我粘贴了代码,我想返回$ .ajax的响应作为函数a()的响应。但是在ajax调用的结果出现之前,它会返回空的f。请帮忙 问题答案: 我猜您正在使用jQuery 1.8+ http://api.jquery.com/jQuery.ajax/ 请阅读细则。 在jQuery 1.8,采用异步的:与jqXHR($ .Deferred)虚假被 弃用 ; 您必须使用complete /

  • 问题内容: 我目前正在编写JavaScript,并对 callback 感到困惑。我发现它不是内置函数…… 我现在正在阅读O’Relly JavaScript 5th Edition,它显示了示例代码,如下所示: 基本上,我想我不了解…… 的总体思路。有人可以编写示例代码来利用上面的优势吗? 问题答案: 回调非常简单又漂亮!由于AJAX调用的性质,您 不会 阻塞脚本的执行,直到您的请求结束(然后它

  • 问题内容: 我有一个php页面,可回显数据库中的行。我想每30秒通过jquery / ajax调用一次。但是我还希望能够随时调用该页面,以便如果我通过表单添加记录,则在表单提交后,我希望通过ajax通过调用页面来立即更新结果。谁能指出我正确的方向或提供一些基本代码,以便我设法找出答案?对于jquery / ajax还是很新的。 问题答案: 如果要在计时器上进行设置,则可以使用JavaScript

  • 问题内容: 在某些情况下, 加号根本不会发布,将发送空格。我已经试过了: 没有运气。有人知道如何解决此问题吗? 问题答案: 应该 或简单地