Получение значения из анонимной функции и onreadystatechange - PullRequest
1 голос
/ 27 августа 2010

У меня есть функция, из которой я хотел бы возвращать значение в виде серии событий при каждом нажатии кнопки.Тем не менее, я не могу понять, как извлечь значение из onreadystatechange.Как я могу сделать так, чтобы я мог вернуть 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]);
}

Ответы [ 2 ]

0 голосов
/ 27 августа 2010

Я бы использовал обратный вызов, в котором вы можете передать функцию, которая запускается, как только ответ будет готов.

Добавить callback в качестве параметра:

function selectVictim(callback)

и затем:

vicString = this.responseText;
vicArray = JSON.parse(vicString);
vicID = Math.floor(Math.random() * (vicArray.length - 1));
if (callback) {
 callback(vicID);
}

Когда вы вызываете функцию, вы можете сделать это:

selectVictim(function(vicID){ 
  console.log('This is the id: ', vicID); 
});

Вы также можете передать функцию в качестве значения, если вы предпочитаете не делать это напрямую. Примечание: это становится немного сложнее, если вы делаете кучу запросов и вам нужно сохранить порядок, в котором они были сделаны, но есть способы справиться с этим.

0 голосов
/ 27 августа 2010

Вы не можете.Ваш обработчик onreadystatechange вызывается long после того, как функция selectVictim вернется.

Здесь у вас есть, так сказать, "асинхронные функции" - т.е. функции, которые генерируют свое возвращаемое значениене сразу, а после определенного асинхронного процесса.

Чтобы справиться с этим, необходимо использовать обратный вызов для предоставления возвращаемого значения:

function selectVictim( callback )
{
    ...
    ...

    request.onreadystatechange = function() {
        ...
        vicArray[vicID] = ...;
        callback( vicArray[vicID] );
    }
}

Обратите внимание на аргумент callback.Тот, кто вызывает эту функцию, должен предоставить другую функцию для этого аргумента.Затем обратите внимание, как selectVictim вызывает обратный вызов, когда возвращаемое значение готово.

Теперь, куда бы вы ни позвонили selectVictim, вы должны изменить свой код с:

function someFunc()
{
    doSomething();

    var vic = selectVictim();

    domeSomethingElseWithVictim( vic );
}

Кому:

function someFunc()
{
    doSomething();

    selectVictim( function( vic ) {

        domeSomethingElseWithVictim( vic );

    } );
}

Достаточно просто?

...