【问题标题】:Javascript asynchronous request NOT workingJavascript异步请求不起作用
【发布时间】:2009-10-04 03:40:50
【问题描述】:

此代码仅在 async 设置为 false 时有效,为什么?

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";
        }
    }
}
  • 我将它导入到一个 html 文档中,如下所示:

    <head>
        <script type="text/javascript" src="contact.js"></script>
    </head>
    
  • 然后像这样使用它:

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

【问题讨论】:

    标签: javascript asynchronous object xmlhttprequest literals


    【解决方案1】:

    因为它是异步的,所以向文本文件发出 HTTP 请求需要时间,因此在 contact.displayData 之后调用回调 contact.storeData

    解决方案是简单地在 storeData 内部调用它,因此它会在向文本文件发出 HTTP 请求并填充 txtDoc 属性后触发。

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

    适合我的完整代码:

    <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>
    

    【讨论】:

    • 如果我只想在回调函数中将来自XMLHttp的响应分配给XMLDoc and TXTDoc而不是显示它们该怎么办?我的方法是将storeData 的语句插入到附加到onreadystatechange 的匿名函数中似乎不起作用。
    • contact.XMLHttp.onreadystatechange = contact.storeData 定义另一个同时调用 storeData 和 displayData 的方法,contact.ajaxCallback 什么的。
    【解决方案2】:

    当您同步执行此操作时:

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

    getData被调用,请求发送并返回,getData完成后返回,然后运行storeData和displayData。 当您异步执行时,getData 会启动请求并立即返回。然后 storeData 和 displayData 在它们准备好之前被调用,所以它们不起作用。请求的结果还没有返回。

    就像 meder 所说,要修复它,您需要在回调函数中进行显示。这样可以确保在 displayData 运行时请求的结果可用。

    【讨论】:

    • 如果我在我的 html 文件中构造一个 if 语句,在调用 storeData 和 displayData 之前检查 getData 是否准备就绪,该怎么办?我该怎么做?
    • 您可以添加一个 while 循环来检查是否完成并休眠,但这样做会阻止脚本加载后的任何内容,直到它完成。最好坚持使用模型的事件驱动/回调。您可以让回调在调用时更改 html。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多