2009-10-04 74 views
0

此代码仅在异步设置为false时起作用,为什么?JavaScript异步请求不起作用

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> 
    

回答

3

由于它是异步的,因此将HTTP请求发送到文本文件需要一些时间,因此回调contact.storeData称为AFTER contact.displayData

解决方法是在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> 
+0

如果我只想在回调函数中将'XMLHttp'的响应分配给'XMLDoc和TXTDoc'而不是显示它们,我该怎么办?我将'storeData'语句插入到'onreadystatechange'的匿名函数中的方法似乎没有用。 – Fortisimo 2009-10-04 12:17:22

+0

'contact.XMLHttp.onreadystatechange = contact.storeData' 定义调用storeData和displayData,'contact.ajaxCallback'或其他方法的另一个方法。 – 2009-10-05 04:44:15

1

执行此操作时同步:

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

getData被调用时,请求被发送和回报,的getData返回它完成后,然后storeData和displayData运行。 当你这样做异步时,getData启动请求并立即返回。然后storeData和displayData在它们准备好之前被调用,所以它们不起作用。请求的结果尚未返回。

像meder说,要解决它,你需要在回调函数中做你的显示。这可确保displayData运行时请求的结果可用。

+0

如果我在调用storeData和displayData之前检查getData是否准备就绪的HTML文件中构造if语句,该怎么办?我会怎么做? – Fortisimo 2009-10-04 13:21:04

+0

您可以添加一个while循环来检查完成和睡眠,但这样做会阻止脚本加载完成之前的任何操作。最好坚持使用事件驱动/回调使用模型。调用时,您可以让回调改变html。 – BaroqueBobcat 2009-10-05 16:42:39