延迟执行(setTimeout)失效了。

5
我有一个页面,希望一直更新文件中的某个值。
基本上,我有一个脚本将一些数据保存到txt文件中,然后我想在网页上显示这些数据。文本文件中的数据每20秒左右会更新一次。
一开始可以正常运行约3分钟左右,然后页面停止更新。有什么想法是为什么会发生这种情况?
function updatepot(elementid) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
                document.getElementById(elementid).innerHTML = this.responseText;
            }
        };
        xmlhttp.open("GET", "../readData.php?q=" + elementid, true);
        xmlhttp.send();

}

function updatePots()
{
       updatepot("pot0");
}
function keeprunning()
{
    setTimeout(updatePots, 1000);
    keeprunning();
}


<?php    
// get the q parameter from URL
$file = $_REQUEST["q"] . ".txt";
$myfile = fopen("potData/".$file, "r") or die("Unable to open file!");
$myData;
while(!feof($myfile)) {
  $myData =  $myData . fgets($myfile);
}
fclose($myfile);
echo $myData;
?>

1
fopen("potData/".$file, "r") 这是一个安全漏洞。$file 可能包含 ..,这就意味着可以进入上级目录,因此恶意用户不仅限于读取 potData 目录中的文件。如果他们可以猜测到相对文件路径,他们可以读取 PHP 用户具有读访问权限的任何 .txt 文件。 - David Knipe
好的,我现在已经将所有定义的路径添加到了 PHP 代码中的一个数组中,然后检查该数组是否包含 $file。 - Jacob
3个回答

6
您的keepRunning方法在setTimeout函数被调用时立即被调用。这意味着它不像您预期的每秒钟被调用,而是被不断地调用(每秒数千次) - 您将很快遇到内存问题,一切都将停止工作。
要解决此问题,请在updatePots函数的末尾调用keepRunning函数:
function updatePots()
{
       updatepot("pot0");
       keeprunning();
}
function keeprunning()
{
    setTimeout(updatePots, 1000);
}

6
如果你想要一个函数定期运行,使用setInterval而不是setTimeout -- 这样,你就不必处理重置间隔的问题。
function updatepots()
{
    updatepot("pot0");
}

window.setInterval(updatePots, 1000);

实际上,在异步代码中使用setTimeout更好。这样程序员可以确保新请求在异步代码解决后发送。 - Mosijava

0

用这种方式调用:

function updatePots()
{
    updatepot("pot0");
    keeprunning();
    setTimeout(updatePots, 1000);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接