Задать вопрос
cbone
@cbone
Серверная инфраструктура

Область видимости переменных JavaScript?

Есть метод:

getData: function (id, url) {<br>
<br>
    var resultJSON;<br>
<br>
    //Настроили AJAX-запрос<br>
    $.ajax({<br>
        type: 'POST',<br>
        dataType: 'JSON',<br>
        url: url,<br>
        data: {<br>
            id: id<br>
        }<br>
    }).done(function (data) {<br>
<br>
        resultJSON = data;<br>
<br>
    }).fail(function (jqXHR, textStatus) {<br>
        $.error("Ошибка загрузки: " + textStatus);<br>
    });<br>
<br>
    return resultJSON;<br>
<br>
}<br>


Почему текущий метод возвращает undifined?

Хотя если вызвать console.log(resultJSON)<br> после строки

resultJSON = data;<br> тогда возвращает нормальный JSON, который пришёл с сервера.

Понимаю, что что-то не так с областью видимости переменных, но как сделать чтобы метод вернул мне значение data в случае успешного получения данных от скрипта?
  • Вопрос задан
  • 4503 просмотра
Подписаться 4 Оценить Комментировать
Решения вопроса 1
@aretmy
Передайте в функцию getData третьим параметром колбэк, который вызывается при получении результата:
  // вызов метода
  obj.getData(id, url, function(data) {
      // здесь обработка данных
   });

// ...

getData: function (id, url, callback) {
    //Настроили AJAX-запрос
    $.ajax({
        type: 'POST',
        dataType: 'JSON',
        url: url,
        data: {
            id: id
        }
    }).done(function (data) {
        callback && callback(data);
    }).fail(function (jqXHR, textStatus) {
        $.error("Ошибка загрузки: " + textStatus);
    });
}
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 4
medved13
@medved13
Ведущий front-end разработчик
$.ajax асинхронен.
Вы его сконфигурировали, повесили обработчики на коллбэки, отправили запрос. И вернули пустоту.
Через какое-то время пришли данные сервера, коллбэк отработал и в resultJSON что-то появилось.
Ответ написан
Igogo2012
@Igogo2012
Вам нужно переписать ваш код так что бы returnJSON был внутри .done(function(data){ ТУТ retrun data; })…
По тому что ваш return происходит раньше чем сервер возвращает данные, по скольку вы запрашиваете данные с сервера асинхронно.
Ответ написан
Комментировать
shcoderAlex
@shcoderAlex
Можно отключить асинхроность «async:false» и всё заработает как вы хотите, но всё замрёт пока не придёт ответ от сервера.
Вот добавил в ваш код
getData: function (id, url) {

    var resultJSON;

    //Настроили AJAX-запрос
    $.ajax({
        type: 'POST',
        async: false,
        dataType: 'JSON',
        url: url,
        data: {
            id: id
        }
    }).done(function (data) {

        resultJSON = data;

    }).fail(function (jqXHR, textStatus) {
        $.error("Ошибка загрузки: " + textStatus);
    });

    return resultJSON;

}

Ответ написан
@egorinsk
> Почему текущий метод возвращает undifined?

Потому, что $.ajax (точнее, XmlHttpRequest) только лишь запускает отправку запроса и сразу же возвращает управление, она не ждет, пока он завершится. И return срабатывает раньше, чем вызовется функция onDone, потому там undefined. Логично же?

> Понимаю, что что-то не так с областью видимости переменных, но как сделать чтобы метод вернул мне значение data в случае успешного получения данных от скрипта?

Никак. Научитесь мыслить асинхронно: не «метод делает запрос и возвращает данные», а «метод отправляет запрос и когда-нибудь потом вызовет функцию onDone».
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы