简体   繁体   中英

Javascript asynchronous request NOT working

This code only works when async is set to false, why?

var contact =
{
    XMLHttp : null,
    XMLDoc : null,
    TXTDoc : null,

    getData : function(dataSource)
    {
        contact.XMLHttp = new XMLHttpRequest();
        contact.XMLHttp.open("GET", dataSource, false);
        contact.XMLHttp.onreadystatechange = contact.storeData;
        contact.XMLHttp.send(null);
    },

    storeData : function()
    {
        if(contact.XMLHttp.readyState == 4 && contact.XMLHttp.status == 200)
        {
            contact.XMLDoc = contact.XMLHttp.responseXML;
            contact.TXTDoc = contact.XMLHttp.responseText;
        }
    },

    displayData : function(elementID)
    {
        if(contact.TXTDoc != null)
            document.getElementById(elementID).innerHTML = contact.TXTDoc;
        else{
        document.getElementById(elementID).innerHTML = "can't do it";
        }
    }
}
  • I import it into a html document like so:

     <head> <script type="text/javascript" src="contact.js"></script> </head> 
  • And use it like so:

     <body id="para"> <script type="text/javascript"> contact.getData("http://localhost/~olatunjigbadamosi/Books/contact.txt"); contact.storeData(); contact.displayData("para"); </script> 

Because it's asynchronous, it takes time to make the HTTP Request to the text file, therefore the callback contact.storeData is called AFTER contact.displayData .

The solution is to simply invoke it inside of storeData, so it fires after it makes the HTTP request to the text file and populates the txtDoc property.

storeData : function()
{
        if(contact.XMLHttp.readyState == 4 && contact.XMLHttp.status == 200)
        {
                contact.XMLDoc = contact.XMLHttp.responseXML;
                contact.TXTDoc = contact.XMLHttp.responseText;
  contact.displayData("para"); 
        }
},

Full code that works for me:

<p id="para"></p>
<button id="foo">go</button>
<script>
var contact =
{
        XMLHttp : null,
        XMLDoc : null,
        TXTDoc : null,

        getData : function(dataSource)
        {
                contact.XMLHttp = new XMLHttpRequest();
                contact.XMLHttp.open("GET", dataSource, true);
                contact.XMLHttp.onreadystatechange = contact.storeData;
                contact.XMLHttp.send(null);
        },

        storeData : function()
        {
                if(contact.XMLHttp.readyState == 4 && contact.XMLHttp.status == 200)
                {
                        contact.XMLDoc = contact.XMLHttp.responseXML;
                        contact.TXTDoc = contact.XMLHttp.responseText;
              contact.displayData("para"); 
                }
        },

        displayData : function(elementID)
        {
                if(contact.TXTDoc != null)
                        document.getElementById(elementID).innerHTML = contact.TXTDoc;
                else{
                document.getElementById(elementID).innerHTML = "can't do it";
                }
        }
},
button = document.getElementById('foo');
button.onclick = function() {
    contact.getData("http://localhost/file.txt");
    contact.storeData();
};

</script>

When you do this synchronously:

contact.getData("http://localhost/~olatunjigbadamosi/Books/contact.txt");
contact.storeData();
contact.displayData("para");

getData is called, the request is sent and returns, getData returns after it finishes and then storeData and displayData run. When you do it async, getData starts the request and returns immediately. Then storeData and displayData are called before they are ready, so they don't work. The results of the request haven't returned yet.

Like meder says, to fix it, you need to do your display in the callback function. That ensures the results from the request are available when displayData is run.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM