Recuperando Valor de Función y onreadystatechange Anónimo
-
01-10-2019 - |
Pregunta
I tiene una función de la que me gustaría devolver un valor como una serie de eventos cada vez que se hace clic en un botón. Sin embargo, no puedo encontrar la manera de recuperar el valor de onreadystatechange. ¿Cómo puedo hacer para que pueda volver 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]);
}
Solución
No se puede. Su manejador onreadystatechange
se llama larga después las funciones selectVictim
devoluciones.
Lo que tenemos aquí es, por así decirlo, "funciones asíncronas" - es decir, funciones que generan su valor de retorno no inmediatamente, pero después de un cierto proceso asíncrono
.Para hacer frente a esto, uno tiene que utilizar una devolución de llamada para proporcionar valor de retorno:
function selectVictim( callback )
{
...
...
request.onreadystatechange = function() {
...
vicArray[vicID] = ...;
callback( vicArray[vicID] );
}
}
Tenga en cuenta el argumento callback
. El que llama a esta función, debe proporcionar otra función para este argumento. Luego cuenta cómo selectVictim
llama a la devolución de llamada cuando el valor de retorno está listo.
Ahora, dondequiera que llama selectVictim
, debe modificar su código de:
function someFunc()
{
doSomething();
var vic = selectVictim();
domeSomethingElseWithVictim( vic );
}
Para:
function someFunc()
{
doSomething();
selectVictim( function( vic ) {
domeSomethingElseWithVictim( vic );
} );
}
Bastante simple?
Otros consejos
Yo usaría una devolución de llamada, en el que se puede pasar a la función que se ejecuta una vez la respuesta está listo.
Agregar callback
como un parámetro:
function selectVictim(callback)
y, a continuación:
vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
if (callback) {
callback(vicID);
}
Cuando se llama a la función que podría hacer esto:
selectVictim(function(vicID){
console.log('This is the id: ', vicID);
});
También puede pasar a la función como valor si prefiere no hacerlo directamente. Nota:. Se pone un poco difícil si usted hace un montón de peticiones y que necesita para preservar el orden en que fueron hechas, pero hay maneras de manejar que