Javascript 我怎样才能让 XHR.onreadystatechange 返回它的结果?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5362462/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I make XHR.onreadystatechange return its result?
提问by Japboy
I'm new to JavaScript programming. I'm now working on my Google Chrome Extension. This is the code that doesn't work... :P
我是 JavaScript 编程的新手。我现在正在开发我的 Google Chrome 扩展程序。这是不起作用的代码......:P
I want getURLInfo
function to return its JSON object, and want to put it into resp
. Could someone please fix my code to get it work?
我希望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...
Thanks in advance.
提前致谢。
回答by Tomalak
You are dealing with an asynchronous function call here. Results are handled when they arrive, not when the function finishes running.
您在这里处理异步函数调用。结果在到达时进行处理,而不是在函数运行完成时进行处理。
That's what callback functions are for. They are invoked when a result is available.
这就是回调函数的用途。当结果可用时调用它们。
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);
}
);
Notes:
笔记:
escape()
has been deprecated since forever. Don not use it, it does not work correctly. UseencodeURIComponent()
.- You couldmake the
send()
call synchronous, by setting theasync
parameter ofopen()
tofalse
. This would result in your UI freezing while the request runs, and you don't want that. - There are many libraries that have been designed to make Ajax requests easy and versatile. I suggest using one of them.
escape()
已被永远弃用。不要使用它,它不能正常工作。使用encodeURIComponent()
.- 您可以
send()
通过将async
参数设置为open()
to使调用同步false
。这会导致您的 UI 在请求运行时冻结,而您不希望这样。 - 有许多库旨在使 Ajax 请求变得简单和通用。我建议使用其中之一。
回答by Pointy
You can't do it at all for asynchronous XHR calls. You cannot make JavaScript "wait" for the HTTP response from the server; all you can do is hand the runtime system a function to call (your handler), and it will call it. However, that call will come a long timeafter the code that set up the XHR has finished.
对于异步 XHR 调用,您根本无法做到。你不能让 JavaScript“等待”来自服务器的 HTTP 响应;您所能做的就是向运行时系统传递一个要调用的函数(您的处理程序),它会调用它。但是,该调用将在设置 XHR 的代码完成后很长时间才会出现。
All is not lost, however, as that handler function can do anything. Whatever it is that you wanted to do with a return value you can do insidethe handler (or from other functions called from inside the handler).
然而,一切都没有丢失,因为该处理程序函数可以做任何事情。无论您想用返回值做什么,您都可以在处理程序内部执行(或从处理程序内部调用的其他函数)。
Thus in your example, you'd change things like this:
因此,在你的例子中,你会改变这样的事情:
xhr.onreadystatechange = function()
{
if (xhr.readyState == 4)
{
var resp = JSON.parse(xhr.responseText);
//
// ... whatever you need to do with "resp" ...
//
}
}
}
回答by Mareks Dunkurs
For small edit talking about post: https://stackoverflow.com/a/5362513/4766489
对于谈论帖子的小编辑:https: //stackoverflow.com/a/5362513/4766489
...
if (typeof callback == "function") {
//var resp = xhr.responseText;
var resp = JSON.parse(xhr.responseText);
callback(resp);
}
...
And when you call
当你打电话时
...
function(data) {
alert(data);
/* now do something with resp */
}
...