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]);
}
¿Fue útil?

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top