根据MySQL数据库值动态更改网站内容

时间:2013-05-18 10:16:33

标签: javascript mysql ajax xmlhttprequest

我想根据值动态更改我的网站。我从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>

1 个答案:

答案 0 :(得分:0)

问题是您正在发送多个异步请求,并且请求未被序列化。请记住,您无法控制请求的响应时间。此外,随着时间的推移,responsedatabasecheck次调用之间的时间量不断增加。对于前者最初,databasecheck将在1.8秒后执行,response将在2秒后执行;差异是200毫秒。第二次,databasecheck将在3.6秒后执行,response将在4秒后执行;差异是400毫秒。

除此之外,请求的响应时间不受您的控制。您提出的第一个请求不一定是第一个要完成的请求。也就是说,即使您将对databasecheckresponse函数的调用序列化,如果您没有序列化XHR调用,您将获得明显随机的结果。也就是说,假设databasecheck返回了x并且您发送了response1.php的请求;当它仍在进行中时,假设第二次请求databasecheck返回y,另一个response2.php请求已启动。现在,根据response1.phpresponse2.php请求的完成顺序,您可能会看到正确或错误的结果。而且,当发生这种情况时,database.php的另一个请求可能会完成,您将再次看到一些不同的结果。这是结果中明显随机性的原因。

您需要做的是序列化对databasecheckresponse函数的调用。也就是说,仅在response请求完成后才启动对database.php的调用。现在,您需要确保请求之间没有竞争条件。这有点麻烦,你可能会失去实时行为。

更好的方法是将调用结果与database.php以及对response1.phpresponse2.php的调用结合起来。也就是说,将逻辑移到服务器端。将代码放在response1.phpresponse2.php中的函数中返回值。假设这些函数名为response1response2。在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中的持续时间,以确保在上一个请求的结束和新请求的开始之间不会有太多延迟。