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]);
}
È stato utile?

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top