2009-10-04 165 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