Получение значения от анонимной функции & onreadystatechange
-
01-10-2019 - |
Вопрос
У меня есть функция, из которой я хотел бы вернуть значение как серию событий, когда нажата кнопка. Тем не менее, я не могу выяснить, как получить значение от 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]);
}
Решение
Вы не можете. Твой onreadystatechange
Обработчик вызывается долго после то 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 );
} );
}
Достаточно просто?
Другие советы
Я бы использовал обратный вызов, в котором вы можете пройти функцию, которая запускается после того, как ответ будет готов.
Добавлять 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);
});
Вы также можете пройти функцию как значение, если вы предпочитаете не делать этого напрямую. Примечание: он становится немного сложно, если вы делаете тонну запросов, и вам нужно сохранить заказ, в котором они были сделаны, но есть способы справиться с этим.