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

Jap*_*boy 16 javascript closures xmlhttprequest

我是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...
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Tom*_*lak 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);
    }
);
Run Code Online (Sandbox Code Playgroud)

笔记:

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