Recupero di valore da Anonymous Funzione & onreadystatechange
-
01-10-2019 - |
Domanda
Ho una funzione da cui vorrei restituire un valore da una serie di eventi ogni volta che si fa clic su un pulsante. Tuttavia, non riesco a capire come recuperare il valore dal onreadystatechange. Come posso fare in modo che possa tornare 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));
}
else alert("Ajax error: No data received");
}
else alert("Ajax Error: " + this.statusText);
}
}
alert(vicArray[vicID]);
}
Soluzione
Non è possibile. Il tuo gestore onreadystatechange
viene chiamato a lungo dopo la funzione selectVictim
rendimenti.
Quello che abbiamo qui è, per così dire, "funzioni asincrone" - vale a dire le funzioni che generano non immediatamente il valore di ritorno, ma dopo un certo processo asincrono
.Per far fronte a questo, si deve utilizzare un callback per fornire valore di ritorno:
function selectVictim( callback )
{
...
...
request.onreadystatechange = function() {
...
vicArray[vicID] = ...;
callback( vicArray[vicID] );
}
}
Si noti l'argomento callback
. Chi chiama questa funzione, deve fornire un'altra funzione per questo argomento. Poi si noti come selectVictim
chiama la richiamata quando il valore di ritorno è pronto.
Ora, ovunque si chiama selectVictim
, è necessario modificare il codice da:
function someFunc()
{
doSomething();
var vic = selectVictim();
domeSomethingElseWithVictim( vic );
}
A:
function someFunc()
{
doSomething();
selectVictim( function( vic ) {
domeSomethingElseWithVictim( vic );
} );
}
abbastanza semplice?
Altri suggerimenti
I userebbe un callback, in cui è possibile passare la funzione che viene eseguito una volta la risposta è pronto.
Add callback
come param:
function selectVictim(callback)
e poi:
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
if (callback) {
callback(vicID);
}
Quando si chiama la funzione che si potrebbe fare questo:
selectVictim(function(vicID){
console.log('This is the id: ', vicID);
});
Si può anche passare la funzione come un valore se si preferisce non farlo direttamente. Nota:. Diventa un po 'difficile se si fanno un sacco di richieste ed è necessario per preservare l'ordine in cui sono stati realizzati, ma ci sono modi per gestire che