Задать вопрос
weranda
@weranda

Почему Ajax запрос не возвращает данные?

Приветствую.
Есть функция и ее вызов:

function getName(user_id) {

            // data
            var data = {}
            data.user_id = user_id
            data = JSON.stringify(data)

            // send
            const request = new XMLHttpRequest();
            request.open("POST", "/test-ajax/");
            request.send(data);

            // get
            request.onload = function() {
                var name = JSON.parse(this.response)
                console.log(name) // <<< тут данные есть
                return name
            }
        }

var user_name = getName(user_id)
console.log(user_name)  // <<< undefined


Внутри функции данные есть (видно через console.log), но в переменную user_name они не попадают. Поясните, пожалуйста, почему так происходит.
  • Вопрос задан
  • 336 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 2
Ошибка у тебя в том, что Ajax-запрос выполняется асинхронно.
Тоесть функция getName вернёт управление в вызывающую функцию ещё до того, как даже будет вызван твой onload.
+ по хорошему onload нужно устанавливать ещё до отправки.
Это раз.

А два - return твой возвращает управление в момент вызова onload, а по тому просто некому будет на той стороне прочитать полученные данные.

Решения два:
1. Использовать промисы. Например так:
function getName(user_id) {
    return new Promise(function(resolve) {
        // data
        var data = {}
        data.user_id = user_id
        data = JSON.stringify(data)

        // send
        const request = new XMLHttpRequest();
        request.open("POST", "/test-ajax/");
        request.send(data);
        request.onload = function() {
            var name = JSON.parse(this.response)
            resolve(name);
        }
    });
}

// Дальше работаем через then
getName(user_id).then(data=>console.log(data));

// Или async/await
const name = await getName(user_id);

В этом примере мы сразу возвращаем объект-промис, который будет завершён внутри onload. А дальше можно с ним работать через async-await или then с коллбэком.

2. Использовать коллбэки (по старинке):
function getName(user_id, callback) {

    // data
    var data = {}
    data.user_id = user_id
    data = JSON.stringify(data)

    // send
    const request = new XMLHttpRequest();
    request.open("POST", "/test-ajax/");
    request.send(data);

    // get
    request.onload = function() {
        var name = JSON.parse(this.response)
        callback(name)
    }
}

var onNameLoaded = function(name) {
    console.log(name)
};
getName(user_id, onNameLoaded);

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

3. Использовать fetch и async/await - мы же в 2022 году живём. (@Mi11er)
async function getName(userId) {
    const response = await fetch("/test-ajax/", {
        method: "POST",
        body: JSON.stringify({"user_id": userId})
    })
    return await response.json();
}

const name = await getName(userId);
Ответ написан
Mi11er
@Mi11er
A human...
Чет как то больно смотреть без feetch...
async function getName(userId) {
    let response  = await feetch("/test-ajax/", {
         method: "POST", 
         body: JSON.stringify(userId)
})
let name = await response.json()

}
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
zkrvndm
@zkrvndm
Архитектор решений
Вы не правильно ответ смотрите.

Смотрите пример:
https://developer.mozilla.org/ru/docs/Web/API/XMLH...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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