可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
in this code this method return undefined despites alert statement print a value ?
function getNearestPoint(idd) { var xmlhttp; var result; if(window.XMLHttpRequest) xmlhttp=new XMLHttpRequest(); else xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); xmlhttp.onreadystatechange=function() { if (xmlhttp.readyState==4 && xmlhttp.status==200) { result= xmlhttp.responseText; alert(result); } } xmlhttp.open("GET","ajax_get_nearest_location.php?id="+idd +"&radius=1",true); xmlhttp.send(); return result; }
回答1:
result isn't defined at that point, it only gets defined once your callback executes. The order of execution:
getNearestPoint
starts - XHR is fired off
getNearestPoint
returns undefiend
- XHR comes back and runs
xmlhttp.onreadystatechange
- result gets set
If you need result from OUTSIDE of this, you should use a callback:
getNearestPoint(idd, cb){ ... xmlhttp.onreadystatechange = function(){ ... cb(result); } }
and your calling code changes from:
var result = getNearestPoint(id);
to:
getNearestPoint(id, function(result){ // do something with result; });
回答2:
result
setting statement executes inside async Ajax function
Because your second if
statement (that sets result
value) doesn't get hit. Why not? Because the moment you send an Ajax request you return the result
value which is still undefined. Ajax call will execute the anonymous function later on and set this result
variable which has been returned long ago.
Ajax is asynchronous and your code isn't taking this into account.
回答3:
This is because of the asychronous nature of Ajax ("Asynchronous JavaScript and XML"): The request will still be running when your code hits return result
. The readystatechange callback will not have been called yet, and the result
variable not set yet.
The usual way to deal with this is to change the architecture of the script: Do whatever you need to do based on result
directly in the onreadystatechange
callback. (or, of course, pass a callback function with the desired actions and execute it in the handler.)