php - Javascript 计时器的准确性

标签 php javascript timer

请注意,这是我上一个问题的后续问题:“How to memorize user's progress through the application? ”。

经过回答,我明白了错误是使用Javascript来判断用户是否赢得了比赛。所以我将逻辑移到了我的 Controller 中:我在用户启动关卡时将 UNIX 时间戳保存到 session 中,并在用户结束关卡时计算差异。如果用户完成关卡所用时间不超过 X 秒,我将允许他/她访问下一关,依此类推。

一切正常,直到我决定引入一个用 Javascript 编写的客户端计时器。计时器明显不如 PHP 计时器准确,因为它依赖于用户的 CPU 而不是服务器的 CPU。所以,这两个定时器是不同步的。当时间范围较长时(例如,用户必须在 4 到 10 秒之间完成关卡),游戏仍然可以运行,但是当时间范围较小(1 或 2 秒)时,游戏将无法按预期运行。即使用户在获胜时间范围内点击,PHP 也会告诉他他没有获胜。

我做了一些尝试,结果如下:

|===========================|
| # |  PHP  |   JS  | Ratio |
|===========================|
| 1 |  6.20 |  5.29 |  1.17 |
| 2 |  7.32 |  6.27 |  1.16 |
| 3 |  2.89 |  2.24 |  1.29 |
| 4 | 22.56 | 20.13 |  1.12 |
| 5 | 50.15 | 45.24 |  1.10 |
|===========================|

(是的,我知道,这是有史以来最糟糕的 ASCII 表。)

这是我使用 jQuery 制作的计时器(我并没有真正接受过这种语言的培训,所以它可能也是有史以来最糟糕的 Javascript 计时器):

$(document).ready(function() {
    window['time'] = {
        'cseconds': 0,
        'dseconds': 0,
        'seconds': 0,
        'minutes': 0,
        'hours': 0
    };

    $("#timer").everyTime(10, function() {
        window['time']['cseconds'] += 1;

        if (window['time']['cseconds'] > 9) {
            window['time']['cseconds'] = 0;
            window['time']['dseconds'] += 1;
        }

        if (window['time']['dseconds'] > 9) {
            window['time']['dseconds'] =  0;
            window['time']['seconds']  += 1;
        }

        if (window['time']['seconds'] > 60) {
            window['time']['seconds'] =  0;
            window['time']['minutes'] += 1;
        }

        if (window['time']['minutes'] > 60) {
            window['time']['minutes'] =  0;
            window['time']['hours']   += 1;
        }

        cseconds = window['time']['cseconds'].toString();
        dseconds = window['time']['dseconds'].toString();
        seconds  = window['time']['seconds'].toString();
        minutes  = window['time']['minutes'].toString();
        hours    = window['time']['hours'].toString();

        if (seconds.length < 2) {
            seconds = "0" + seconds;
        }
        if (minutes.length < 2) {
            minutes = "0" + minutes;
        }
        if (hours.length < 2) {
            hours = "0" + hours;
        }

        $("#timer").text(hours + ":" + minutes + ":" + seconds + "." + dseconds + cseconds);
    });
});

我尝试过不同的解决方案,例如 AJAX:首先,计时器仅依赖于 AJAX 请求(这导致了数千个 HTTP 请求),但它仍然不够精确。然后我将其修改为每 X 秒与 PHP 同步一次,但它也不起作用。

有没有人有任何提示?

最佳答案

如果您通过在事件的开始和结束时执行 new Date() 来为事件计时,并比较它们之间耗时差,您将使用 javascript 获得非常准确的计时。现代浏览器中计时器的精度通常为几毫秒,而在旧版浏览器中不低于 15 毫秒。

您的代码看起来像是在尝试使用间隔计时器和计数间隔。那不会很准确。因为 javascript 是单线程的,所以 javascript 计时器触发的确切时间不是很精确,因此不应依赖它来准确计时事件。换句话说,测量经过的系统时间比计算已触发的计时器间隔要准确得多。

关于php - Javascript 计时器的准确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9038057/

相关文章:

PHP类设计问题

javascript - 将多选显示为普通选择

javascript - 从可观察数组中获取属性值的总和

Java GUI 未加载

php - 不同网站上的多个平台的单一登录

javascript - 从 JSON 表创建可点击的搜索结果

php - 是否有将PHP函数与Go版本进行比较的引用?

javascript - 从 Parse Cloud 销毁对象是不可靠的

ios - 检查用户是否导航到 iOS 中的另一个 View

java - 我的计时器 GUI 面板出了问题