【发布时间】:2012-12-10 15:07:21
【问题描述】:
我的背景是传统的编译型面向对象语言,例如 C++ 和 .NET 编程,现在我正在为一个新项目涉足一些 JavaScript。我在涉足 AJAX 并遇到了一个令人困惑的方面,即浏览器如何管理对象。
[编辑 #2] - 活动内容脚本的更改
我有一个包含三个按钮的练习页面,每个按钮使用XMLHttpRequest 对象更新<textarea>:
- 按钮 1 使用 slowtime.php 中的文本内容更新 TextArea1
- 按钮 2 使用 slowtime.php 中的文本内容更新 TextArea2
- 按钮 3 使用 fasttime.php 中的文本内容更新 TextArea3
slowtime.php 和 fasttime.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 发送第二个请求会如何影响第一个请求的响应时间?这可能是服务器端问题吗?
【问题讨论】:
-
在您的
xmlhttp.onreadystatechange函数中,您是否应该使用this.responseText而不是xmlhttp.responseText? -
@JoshuaD.Boyd 这不应该做任何其他事情,因为
xmlhttp变量位于loadXMLDoc内的本地范围内。 -
在
onreadystatechange函数中将所有对xmlhttp的引用更改为this也有效,并且也会产生相同的行为 -
@nicholas 你能包含 slowrand.php 和 fastrand.php 的源代码吗?
-
@seliopou:你让我发现了服务器端代码的一个主要问题。对于诊断,slowrand 正在打开并写入文件。第二个 slowrand 调用试图打开一个锁定的文件,因此退出错误 - 长话短说,使用不同的 php 代码来编写时间戳,我得到不同的结果。请求没有被合并,但是它们的时间被搞砸了。
标签: javascript html ajax xmlhttprequest