好的,过去两天我一直试图让这个工作起来,我无法弄清楚我做错了什么。我有一个名为“ping”的函数进行计算,我有一个回调函数来检索计算值,但我不断得到的是未定义的!
var test;
var p = ping('apple.com', function (num) {
test = num;
console.log(test); //this works, the value is displayed in the console.
});
console.log("p: " +p); //says undefined
console.log("test: " +test); //says undefined
有人能告诉我我做错了什么吗?谢谢!
修改 这是ping函数:
function ping(host, pong) {
var started = new Date().getTime();
var http = new XMLHttpRequest();
http.open("GET", "http://" + host, /*async*/true);
http.onreadystatechange = function() {
if (http.readyState == 4) {
var ended = new Date().getTime();
var milliseconds = ended - started;
if (pong != null) {
pong(milliseconds);
//console.log(milliseconds);
return milliseconds;
}
}
};
try {
http.send(null);
} catch(exception) {
// this is expected
}
}
答案 0 :(得分:2)
ping
是一个异步函数 - 这意味着回调函数会在“稍后某个时刻”执行。
var test;
ping('apple.com', function (num) {
// this is called "at some point later" ..
test = num;
console.log(test);
});
// .. but this executes IMMEDIATELY after the ping(..) function is called ..
// .. which is before the callback (and thus assignment to `test`)
console.log("test: " +test);
解决方案是仅因回调事件而继续工作。这可以以不同的方式隐藏 - 例如回调,承诺和期货/可观察 - 但它始终是相同的过程。
ping(..)
也返回undefined(或者更确切地说,它根本不是return
),这解释了为什么p
未定义 - 但这是次要的并且与异步无关性质。
答案 1 :(得分:-1)
你可以使用同步AJAX。
function ping(host,pong){
var http = new XMLHttpRequest();
http.open("GET", "http://" + host, /*not async*/false);
http.send(null);
if(pong)pong(http.responseText);
return http.responseText;
};
否则您将无法返回http.responseText
。
然而,这种技术并不是最佳实践,因为它会导致页面上的所有其他Javascript停止,直到请求完成。如果服务器需要很长时间才能回答,那么您的页面将无法响应。非常讨厌用户。
请注意,如果您在问题中的代码中显示,尝试将AJAX发送到其他域时会出错。