在javascript中以毫秒为单位获得时间的更好方法?

Col*_*tru 132 javascript

JavaScript中是否存在使用日期对象获取时间(以毫秒为单位)的替代方法,或者至少是重用该对象的方法,而不必在每次需要获取此值时都实例化新对象?我问这个是因为我试图在JavaScript中创建一个简单的游戏引擎,并且在计算"delta frame time"时,我必须每帧创建一个新的Date对象.虽然我并不太担心这种性能影响,但我对这个对象返回的确切时间的可靠性存在一些问题.

我在动画中得到一些奇怪的"跳跃",每隔一秒左右,我不确定这是否与JavaScript的垃圾收集或更新如此之快的Date对象的限制有关.如果我将delta值设置为某个常量,那么动画如果完全平滑,那么我很确定这个"跳跃"与我得到时间的方式有关.

我能给出的唯一相关代码是我计算增量时间的方式:

prevTime = curTime;
curTime = (new Date()).getTime();
deltaTime = curTime - prevTime;
Run Code Online (Sandbox Code Playgroud)

在计算运动/动画时,我将常数值乘以增量时间.

如果没有办法通过使用Date对象来避免以毫秒为单位获取时间,那么会增加一个变量的函数(自游戏开始以来经过的时间,以毫秒为单位),并使用SetTimer函数以一定的速率调用每毫秒一次是一个有效和可靠的替代方案吗?

编辑:我现在已经在不同的浏览器中测试了我的代码,似乎这种"跳跃"实际上只在Chrome中显而易见,而不是在Firefox中.但是,如果有一种方法在两种浏览器中都有效,那仍然会很好.

Joe*_*hts 162

试试Date.now().

跳过很可能是由于垃圾收集.通常可以通过尽可能多地重用变量来避免垃圾收集,但我不能具体说明可以使用哪些方法来减少垃圾收集暂停.

  • 只是抬头:这在IE8及以下版本中无效 (22认同)
  • @Prozi +1 .. IE真的很糟糕,当我在网络编程时我真的不在乎IE,只是chrome和firefox .......... (4认同)
  • @TechLife你也应该给Android,Safari和Opera浏览器一个思路,但我同意IE是一堆垃圾.我的意思是MS已经放弃并且正在W10中实现新的浏览器 (3认同)

ngr*_*man 47

据我所知,你只能抽出约会时间.

Date.now是解决方案,但无处可用:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date/now.

var currentTime = +new Date();
Run Code Online (Sandbox Code Playgroud)

这为您提供当前时间(以毫秒为单位).

为了你的跳跃.如果根据增量帧时间正确计算插值并且没有一些舍入数字错误,我打赌垃圾收集器(GC).

如果循环中有很多创建的临时对象,垃圾收集必须锁定线程以进行一些清理和内存重组.

使用Chrome,您可以查看GC在时间轴面板中花费的时间.

编辑:由于我的答案,Date.now()应该被认为是最好的选择,因为它支持无处不在,IE> = 9.

  • `+`简单地将`Date`转换为`Number`,给出标准的unix时间戳,以毫秒为单位.您可以通过调用`(new Date()).getTime()`显式获取此值 (32认同)
  • @mikenelson:对我来说并不可怕,当你知道强制是如何工作的时候,这是显而易见的.那就说,'Date.now()`现在是首选,因为它的支持现在足够大了. (9认同)
  • `+`在`+ new`中起什么作用? (4认同)
  • @TravisJ 很棒的快捷方式?要检索已存在于您的计算机中的数值,您可以创建一个对象,调用一个运算符来测试 int 并触发一个调用函数 (valueOf) 的转换,该函数调用类转换方法,该函数调用函数 (getTime),最终检索值。然后对象被抛弃到它的命运,在循环的 1000 次迭代之后,你有 1000 个删除的 Date 对象需要垃圾收集挂在那里,这些对象突然全部转储在一起,当你的计算机滞后时,你想知道发生了什么。:) 惊人的! (2认同)

Chr*_*een 47

我知道这是一个非常古老的线程,但为了使事情保持最新且更具相关性,您可以使用更准确的performance.now()功能在javascript中获得更精细的粒度计时.

window.performance = window.performance || {};
performance.now = (function() {
    return performance.now       ||
        performance.mozNow    ||
        performance.msNow     ||
        performance.oNow      ||
        performance.webkitNow ||            
        Date.now  /*none found - fallback to browser default */
})();
Run Code Online (Sandbox Code Playgroud)

  • 最后一个选择应该是`Date.now`而不是匿名函数表达式 (2认同)
  • || function(){return new Date().getTime()} (2认同)
  • 值得注意的是`performance.now()`给出了单调时间,与`Date`的时间不同.这意味着每个后续调用都保证返回不小于前一个值的值. (2认同)

小智 6

如果您有日期对象

var date = new Date('2017/12/03');
Run Code Online (Sandbox Code Playgroud)

然后在javascript中有一个内置方法来获取毫秒格式的日期,该值是valueOf()

date.valueOf(); //1512239400000 in milliseconds format
Run Code Online (Sandbox Code Playgroud)