我想根据值动态更改我的网站。我从MySQL数据库中检索数据,并希望更改尽可能接近实时。我有一些代码可以在某种程度上做我想要的,但值的更新似乎失败,起初它可以工作,然后在几次调用之后它似乎只是在两个值之间随机切换。
我有三个php页面,一个用于从数据库中检索值(database.php),另外两个用于根据数据库值(response1.php和response2.php)生成响应。我不认为这些页面是问题的一部分,因为我已经检查过它们返回值并返回我想要的内容。项目的第二部分(以及它可能失败的地方)是我的主要html页面(下面)。我不确定我是否选择了最好的技术来解决我的问题,或者是否有更好的方法来做到这一点。
<html>
<head>
<script type="text/javascript">
var databaseanswer, xmlhttp;
function databasecheck() {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "database.php", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
databaseanswer = xmlhttp.responseText;
document.getElementById("database").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.send();
}
function response() {
if (databaseanswer == "No Tag") {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "response1.php", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("response").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.send();
}
else {
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "response2.php", true);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("response").innerHTML = xmlhttp.responseText;
}
};
xmlhttp.send();
}
}
setInterval(databasecheck, 1800);
setInterval(response, 2000);
</script>
</head>
<body>
<p> this is a test site </p>
<p> response from server: </p>
<div id="response">
</div>
<p> answer from database: </p>
<div id="database">
</div>
</body>
</html>
好的,这是我编辑过的代码:
<html>
<head>
<script>
function database(){
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","responsedatabase.php",false);
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("database").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.send();
}
setInterval(database,1000);
</script>
</head>
<body>
<p>answer from database: </p><div id="database"></div>
</body>
</html>
答案 0 :(得分:0)
问题是您正在发送多个异步请求,并且请求未被序列化。请记住,您无法控制请求的响应时间。此外,随着时间的推移,response
和databasecheck
次调用之间的时间量不断增加。对于前者最初,databasecheck
将在1.8秒后执行,response
将在2秒后执行;差异是200毫秒。第二次,databasecheck
将在3.6秒后执行,response
将在4秒后执行;差异是400毫秒。
除此之外,请求的响应时间不受您的控制。您提出的第一个请求不一定是第一个要完成的请求。也就是说,即使您将对databasecheck
和response
函数的调用序列化,如果您没有序列化XHR调用,您将获得明显随机的结果。也就是说,假设databasecheck
返回了x
并且您发送了response1.php
的请求;当它仍在进行中时,假设第二次请求databasecheck
返回y
,另一个response2.php
请求已启动。现在,根据response1.php
和response2.php
请求的完成顺序,您可能会看到正确或错误的结果。而且,当发生这种情况时,database.php
的另一个请求可能会完成,您将再次看到一些不同的结果。这是结果中明显随机性的原因。
您需要做的是序列化对databasecheck
和response
函数的调用。也就是说,仅在response
请求完成后才启动对database.php
的调用。现在,您需要确保请求之间没有竞争条件。这有点麻烦,你可能会失去实时行为。
更好的方法是将调用结果与database.php
以及对response1.php
和response2.php
的调用结合起来。也就是说,将逻辑移到服务器端。将代码放在response1.php
和response2.php
中的函数中返回值。假设这些函数名为response1
和response2
。在database.php
中。根据数据库值调用这些函数之一。将结果与数据库值一起放在关联数组中,并将响应作为JSON格式的字符串返回。这样,您将减少一个请求,并且没有同步问题。
更新后
您需要在更新后的代码中执行以下操作:
var requestInProgress = false;
function database() {
if(requestInProgress) {
return;
}
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","responsedatabase.php",false);
xmlhttp.onreadystatechange=function() {
if (xmlhttp.readyState == 4) {
requestInProgress = false;
if(xmlhttp.status==200) {
document.getElementById("database").innerHTML=xmlhttp.responseText;
}
}
}
requestInProgress = true;
xmlhttp.send();
}
您还可以减少setInterval
中的持续时间,以确保在上一个请求的结束和新请求的开始之间不会有太多延迟。