Как объект XMLHttpRequest () делает это? - PullRequest
2 голосов
/ 09 марта 2012

Я некоторое время изучал JavaScript, и когда я начал изучать AJAX, я увидел то, чего раньше никогда не видел, что любопытно.

Возьмем, к примеру, этот пример кода.

var receiveReq = XMLHttpRequest();      
//Initiate the asyncronous request.
function sayHello() {
    //If our XMLHttpRequest object is not in the middle of a request, start the new asyncronous call.
    if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
        //Setup the connection as a GET call to SayHello.html.
        //True explicity sets the request to asyncronous (default).
        receiveReq.open("GET", 'SayHello.html', true);
        //Set the function that will be called when the XMLHttpRequest objects state changes.
        receiveReq.onreadystatechange = handleSayHello; 
        //Make the actual request.
        receiveReq.send(null);
    }           
}

function handleSayHello() {
    //Check to see if the XmlHttpRequests state is finished.
    if (receiveReq.readyState == 4) {
        //Set the contents of our span element to the result of the asyncronous call.
        document.getElementById('span_result').innerHTML = receiveReq.responseText;
    }           
}

После вызова этой функции браузер продолжает вызывать handleSayHello () несколько раз.Что заставляет браузер делать это?Я никогда раньше такого не видел ни в JavaScript, ни в любом другом языке, и для меня это не имеет смысла.Как это работает?Есть ли в JavaScript другие вещи, подобные этому?

Кроме того, что бы произошло, если бы receiveReq.readyState не было 0 или 4, когда оператор if в sayHello() выполнялся?

Редактировать:

Я сделал небольшое изменение в функции sayHello() и теперь это выглядит так.

function sayHello() {
    //If our XmlHttpRequest object is not in the middle of a request, start the new asyncronous call.
    if (receiveReq.readyState == 4) {
        //Setup the connection as a GET call to SayHello.html.
        //True explicity sets the request to asyncronous (default).
        receiveReq.open("GET", 'SayHello.html', true);
        //Set the function that will be called when the XmlHttpRequest objects state changes.
        receiveReq.onreadystatechange = handleSayHello; 
        //Make the actual request.
        receiveReq.send(null);
    }     
    else
        alert("readyState = " + receiveReq.readyState);      
}

Код все еще работает!Я обнаружил, что оператор if выполняется один раз.Первый раз - когда readyState = 0, а второй - когда readyState = 4. Как это произошло?

Вот полный исходный код.

<html>
    <head>
        <title>The Hello World of AJAX</title>
        <script language="JavaScript" type="text/javascript">
            //Gets the browser specific XMLHttpRequest Object
            function getXmlHttpRequestObject() {
                if (window.XMLHttpRequest) {
                    return new XMLHttpRequest(); //Not IE
                } else if(window.ActiveXObject) {
                    return new ActiveXObject("Microsoft.XMLHTTP"); //IE
                } else {
                    //Display your error message here. 
                    //and inform the user they might want to upgrade
                    //their browser.
                    alert("Your browser doesn't support the XmlHttpRequest object.  Better upgrade to Firefox.");
                }
            }           
            //Get our browser specific XMLHttpRequest object.
            var receiveReq = getXmlHttpRequestObject();     
            //Initiate the asyncronous request.
            function sayHello() {
                //If our XMLHttpRequest object is not in the middle of a request, start the new asyncronous call.
                if (receiveReq.readyState == 4 || receiveReq.readyState == 0) {
                    //Setup the connection as a GET call to SayHello.html.
                    //True explicity sets the request to asyncronous (default).
                    receiveReq.open("GET", 'SayHello.html', true);
                    //Set the function that will be called when the XMLHttpRequest objects state changes.
                    receiveReq.onreadystatechange = handleSayHello; 
                    //Make the actual request.
                    receiveReq.send(null);
                }           
            }
            //Called every time our XMLHttpRequest objects state changes.
            function handleSayHello() {
                //Check to see if the XMLHttpRequest's state is finished.
                if (receiveReq.readyState == 4) {
                    //Set the contents of our span element to the result of the asyncronous call.
                    document.getElementById('span_result').innerHTML = receiveReq.responseText;
                }
            }
            </script>
    </head>
    <body>
        <!-- Clicking this link initiates the asyncronous request -->
        <a href="javascript:sayHello();">Say Hello</a><br />
        <!-- used to display the results of the asynchronous request -->
        <span id="span_result"></span>
    </body>
</html>

Содержимое файла SayHello.htmlэто просто

hello, world

Ответы [ 2 ]

3 голосов
/ 09 марта 2012

Следующая строка кода подключает событие onreadystatechange к вашей функции handleSayHello. onreadystatechange запускается несколько раз в течение жизненного цикла XMLHttpRequestrequest, следовательно, функция handle выполняется более одного раза.

receiveReq.onreadystatechange = handleSayHello; 

Эта статья довольно информативна в отношении значений и изменений в состоянии готовности.

0 голосов
/ 09 марта 2012

каждый раз, когда вы отправляете запрос, вам нужен новый экземпляр XHR
когда xhr readyState изменился, слушатель события onreadystatechange будет вызывать
так что

function sayHello() {
    var receiveReq = new XMLHttpRequest();      
    receiveReq.open("GET", 'SayHello.html', true);
    receiveReq.onreadystatechange = function  (  ) {
        if (receiveReq.readyState == 4 ) {
        //do sth.
            handleSayHello ()
        }
    }; 
    receiveReq.send(null);
}
function handleSayHello (  ) {

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...