如何让XHR.onreadystatechange返回其结果?

时间:2011-03-19 13:46:24

标签: javascript xmlhttprequest closures

我是JavaScript编程的新手。我现在正在处理我的Google Chrome扩展程序。这是不起作用的代码......:P

我希望getURLInfo函数返回其JSON对象,并希望将其放入resp。有人可以修改我的代码以使其正常工作吗?

function getURLInfo(url)
{
    var xhr = new XMLHttpRequest();
    xhr.open
        (
            "GET",
            "http://RESTfulAPI/info.json?url="
                + escape(url),
            true
        );
    xhr.send();
    xhr.onreadystatechange = function()
    {
        if (xhr.readyState == 4)
        {
            return JSON.parse(xhr.responseText);
        }
    }
}
var resp = getURLInfo("http://example.com/") // resp always returns undefined...

提前致谢。

3 个答案:

答案 0 :(得分:24)

您正在处理异步函数调用。结果在到达时处理,而不是在函数完成运行时处理。

这就是回调函数的用途。当结果可用时调用它们。

function get(url, callback) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            // defensive check
            if (typeof callback === "function") {
                // apply() sets the meaning of "this" in the callback
                callback.apply(xhr);
            }
        }
    };
    xhr.send();
}
// ----------------------------------------------------------------------------


var param = "http://example.com/";                  /* do NOT use escape() */
var finalUrl = "http://RESTfulAPI/info.json?url=" + encodeURIComponent(param);

// get() completes immediately...
get(finalUrl,
    // ...however, this callback is invoked AFTER the response arrives
    function () {
        // "this" is the XHR object here!
        var resp  = JSON.parse(this.responseText);

        // now do something with resp
        alert(resp);
    }
);

注意:

  • escape()自永远被弃用。不要使用它,它无法正常工作。使用encodeURIComponent()
  • 您可以通过将send()的{​​{1}}参数设置为async 使open()调用同步。这会导致您的UI在请求运行时冻结,并且您不希望这样。
  • 有许多库旨在使Ajax请求变得简单和通用。我建议使用其中一个。

答案 1 :(得分:3)

根本不能对异步XHR调用执行此操作。你不能让JavaScript“等待”来自服务器的HTTP响应;你所能做的就是将运行时系统交给一个函数来调用(你的处理程序),然后调用它。但是,在设置XHR的代码完成后,该调用将会很长时间

然而,

所有都不会丢失,因为该处理函数可以执行任何。无论您想要使用返回值做什么,您都可以在处理程序(或从处理程序内部调用的其他函数)内部

因此,在您的示例中,您将更改以下内容:

    xhr.onreadystatechange = function()
    {
        if (xhr.readyState == 4)
        {
            var resp = JSON.parse(xhr.responseText);
            //
            // ... whatever you need to do with "resp" ...
            //
        }
    }
}

答案 2 :(得分:-1)

关于帖子的小编辑:https://stackoverflow.com/a/5362513/4766489

...
if (typeof callback == "function") {
     //var resp  = xhr.responseText;
     var resp  = JSON.parse(xhr.responseText);
     callback(resp);
}
...

当你打电话

...
function(data) {
    alert(data);
    /* now do something with resp */
}
...