Проблема с асинхронным кодом, возвращающим неверную переменную - PullRequest
0 голосов
/ 19 октября 2019

Я новичок в кодировании с использованием AJAX и не могу понять, почему следующая асинхронная функция, которая использует обратный вызов, не будет работать должным образом. Переменная PC является глобальной и для тестов установлена ​​на PC = 666. ПК следует присвоить значение 1, которое читается из файла XML. Код, который я использую ниже:

function makePlaceRequest(XMLaddress, callback) {
        httpRequest = new XMLHttpRequest();
        // alert('Starting XML read');
        if (!httpRequest) {
            alert('Warning :( Cannot create an XMLHTTP instance');
            return false;
        }

        // httpRequest.onreadystatechange = getPlace;

        // State changes

        httpRequest.onreadystatechange = function() {
            try {
                if (httpRequest.readyState === XMLHttpRequest.DONE) {
                    if (httpRequest.status === 200) {
                        var xmldoc = httpRequest.responseXML;
                        var root_node = xmldoc.getElementsByTagName('placecode').item(0);
                        PC = root_node.firstChild.data;
                        // callback();
                    }
                    else {
                        alert('There was a problem with the request.');
                    }
                }
            }
            catch( e ) {
                alert('Caught Exception: ' + e.description);
            }
        }

        httpRequest.open('GET', XMLaddress);
        // httpRequest.open('GET', '/xml/Places.xml');
        httpRequest.send();

        callback();
    }

    makePlaceRequest('/xml/Places.xml', function() {
        alert(PC);
        alert('Completed XML read');
        alert(PC);
    });

Я вызываю функцию следующим образом: makePlaceRequest('/xml/Places.xml'); Первое (ПК) предупреждение отображает 666, то есть обратный вызов вызывается до того, как файл XML был успешно прочитан. и второе оповещение ПК отображает правильное значение, т. е. 1, я полагаю, последнее происходит из-за задержки, вызванной информационным сообщением (чтение завершено в XML). Я не могу понять, почему функция обратного вызова вызывается вообще до завершения обработки.

1 Ответ

0 голосов
/ 19 октября 2019

Вызов httpRequest.send () является асинхронным и поэтому не будет ожидать завершения вызова AJAX. Следовательно, весьма вероятно, что callback () будет вызван до того, как вызов AJAX получит ответ, и этот ответ будет обработан.

Когда ответ получен, поток программы будет прерван для запуска обработчика onreadystatechange. После завершения обработки обработчиком onreadystatechange прерванный поток программы возобновляется.

Закомментированный обратный вызов () в обработчике onreadystatechange гарантирует, что ваш обратный вызов () будет вызываться только после получения и обработки ответа.

...