Retrieving Value from Anonymous Function & onreadystatechange
I have a function from which I would like to return a value as a series of events whenever a button is clicked. However, I can't figure out how to retrieve the value from onreadystatechange. How can I make it so I can return vicArray[vicID]
?
function selectVictim()
{
var vicString;
var vicArray;
var vicID;
var params = "url=queenofsheep.com/Sheep/victims.php";
var request = new ajaxRequest();
request.open("POST", "victims.php", true);
request.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded");
request.setRequestHeader("Content-Length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);
request.onreadystatechange = function ()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
if (this.responseText != null )
{
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
}
开发者_JAVA百科else alert("Ajax error: No data received");
}
else alert("Ajax Error: " + this.statusText);
}
}
alert(vicArray[vicID]);
}
You can't. Your onreadystatechange
handler gets called long after the selectVictim
function returns.
What you have here is, so to say, "asynchronous functions" - i.e. functions that generate their return value not immediately, but after a certain asynchronous process.
To deal with this, one has to use a callback to provide return value:
function selectVictim( callback )
{
...
...
request.onreadystatechange = function() {
...
vicArray[vicID] = ...;
callback( vicArray[vicID] );
}
}
Note the callback
argument. Whoever calls this function, must provide another function for this argument. Then note how selectVictim
calls the callback when the return value is ready.
Now wherever you call selectVictim
, you must modify your code from:
function someFunc()
{
doSomething();
var vic = selectVictim();
domeSomethingElseWithVictim( vic );
}
To:
function someFunc()
{
doSomething();
selectVictim( function( vic ) {
domeSomethingElseWithVictim( vic );
} );
}
Simple enough?
I would use a callback, in which you can pass the function that runs once the response is ready.
Add callback
as a param:
function selectVictim(callback)
and then:
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
if (callback) {
callback(vicID);
}
When you call the function you could do this:
selectVictim(function(vicID){
console.log('This is the id: ', vicID);
});
You can also pass the function as a value if you prefer not to do it directly. Note: it gets a little tricky if you make a ton of requests and you need to preserve the order in which they were made, but there are ways to handle that.
精彩评论