2012-12-24 80 views
9

我的背景是傳統編譯的面嚮對象語言,例如C++和.NET編程,現在我正在爲一個新項目引入一些JavaScript。我涉足AJAX,並對瀏覽器管理對象的方式感到困惑。xmlhttprequest對象如何在Javascript中創建,合併和銷燬

[編輯#2] - 改變在活動內容的腳本

我有每個更新一個<textarea>使用XMLHttpRequest對象三個按鈕的做法頁:

  1. 按鈕更新1個TextArea1文本內容來自slowtime.php
  2. 按鈕2更新TextArea2的文本內容從slowtime.php
  3. 按鈕3更新TextArea3從fasttime.php

文本內容在哪裏slowtime.phpfasttime.php都與兩個時間戳返回文本/ HTML頁面的簡單腳本:一個時頁面加載,一段時間過後。

每次單擊一個按鈕時,每個按鈕都能正常工作。如果我在第一個請求完成之前單擊按鈕2,然後單擊按鈕3,則更新仍然按預期工作。

如果在第一個請求完成之前單擊按鈕1然後按鈕2,則TextArea1和TextArea2會接收到正確的值;然而,onreadystatechange事件調用同時發生,即第一次響應遲到,並且僅在第二次響應到達時才處理。

示例代碼

網站

<!DOCTYPE html> 
<html> 
<head> 
<script> 
function loadXMLDoc(url,target) 
{ 
var xmlhttp; 
xmlhttp=new XMLHttpRequest(); 

xmlhttp.onreadystatechange=function() 
    { 
    if (xmlhttp.readyState==4 && xmlhttp.status==200) 
    { 
    document.getElementById(target).value=xmlhttp.responseText; 
    } 
    } 
xmlhttp.open("POST",url,true); 
xmlhttp.send(); 
} 
</script> 
</head> 

<body> 
<form> 

<input type="button" value="Button 1" onClick="loadXMLDoc('slowtime.php','TextArea1')"/> 
<input type="button" value="Button 2" onClick="loadXMLDoc('slowtime.php','TextArea2')"/> 
<input type="button" value="Button 3" onClick="loadXMLDoc('fasttime.php','TextArea3')"/> 

<div><textarea id="TextArea1"></textarea></div> 
<div><textarea id="TextArea2"></textarea></div> 
<div><textarea id="TextArea3"></textarea></div> 

</form> 
</body> 
</html> 

PHP代碼(slowtime.php

<?php 
    echo date('h:i:s') . "\n"; 
    sleep(5); 
    echo date('h:i:s') . "\n"; 
?> 

問題[修正]

瀏覽器如何管理XMLHttpRequest對象?按下按鈕2和3表示每次按下都會實例化一個新對象,並且每個按鈕都有獨立的事件處理程序。如果對象活過了初始函數調用(因爲它們的事件處理程序存活),它們何時從內存中清除/被破壞?

如果XMLHttpRequests是單獨的對象,那麼如何向同一個URL發送第二個請求會影響第一個請求的響應時間?可能這是一個服務器端問題?

+0

在你的'xmlhttp.onreadystatechange'函數中,你應該使用'this.responseText'而不是'xmlhttp.responseText'嗎? –

+1

@ JoshuaD.Boyd由於'xmlhttp'變量位於'loadXMLDoc'內的本地範圍內,所以不應該做任何事情。 – Tyilo

+0

在'onreadystatechange'函數中將'xmlhttp'所有對'this'的引用都改變了,並且也產生了相同的行爲 – nicholas

回答

2

上下文到XMLHttpRequest永遠不會被刪除,除非在對象上顯式調用刪除。在這種情況下:xmlhttp。你真的應該以某種方式跟蹤這個var並且清理它,如果你想讓你的應用程序運行精簡和清潔。 Javascript最初是爲網頁設計的,因此它傾向於讓事情變得瘋狂,除非你自己阻止它。

否則,一旦該對象不再可用於任何其他函數或者有任何剩餘的回調,瀏覽器的垃圾回收器就會消除該對象。

至於你同時發生的事件的問題,我不能自己再現這個問題,這確實讓我相信你的php配置有問題。有可能你的服務器不允許多個腳本一次運行嗎?

這裏就是你們的榜樣我的服務器上,與一對夫婦的細微變化: http://www.seijinohki.net/test.php

+0

感謝您將代碼發佈到不同的測試服務器上。當我在Chrome或Safari中測試您的網站時,我會得到與上述rambo相同的結果 - 兩個文本區域都具有相同的值。同時,Firefox,IE9和Silk不會。您的頁面在傲遊移動瀏覽器中完全不起作用。 – nicholas

+0

很久以後,接受這個答案作爲答案,因爲它直接處理請求的上下文。一個有趣的討論,並至少在目前顯示,Web開發/瀏覽器/等仍然是什麼,但他們如何執行腳本統一.. – nicholas

1

這是一個瀏覽器的問題。

  • 鉻23 & 26這樣的行爲。
  • 歌劇院12犯規
  • IE 9犯規
  • 火狐17犯規

如果您的網址獨特,如slowtime.php?1slowtime.php?2之後,Chrome的行爲不再這樣。

btw-在我的測試中,chrome用相同的值更新了兩個textareas - 第一個請求的值。並且它們都在第一次請求結束時更新,而不是在第二次結束時更新。這肯定是一個錯誤,因爲它顯然是錯誤的。我通過網絡服務器日誌驗證第二個請求永遠不會被髮送。

+0

當我在kokorohakai的服務器上使用Chrome或Safari進行測試時,我看到相同你做的結果 - 兩個文本區域都獲得相同的值,並根據第一個請求計時。同時在我的測試服務器(本地主機)上,我得到了兩個不同的值,第二個與時間同步。這使我相信答案非常複雜,而且基於瀏覽器和服務器行爲。 – nicholas

+0

@nicholas你的本地服務器日誌是否顯示兩個請求?仍然,chrome只在我的測試中發送一個請求的事實表明它存在一個錯誤(或一個奇怪的特性)。 – goat