首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >断点不正确的秒表

断点不正确的秒表
EN

Stack Overflow用户
提问于 2016-07-09 17:02:41
回答 3查看 159关注 0票数 9

我有一个主秒表与4个迷你秒表为每一步。经过一段时间之后,下面是一个定时器应该如何看上去的示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
MAIN:  00 : 14 : 57
-------------------
MINI1: 00 : 04 . 17
MINI2: 00 : 06 . 40
MINI3: 00 : 02 . 54
MINI4: 00 : 01 . 46

迷你计时器应该与主定时器相加,就像它们在这种情况下所做的那样。用我目前的计时器,它似乎总是离.02毫秒,所以在这种情况下,它们加起来就是00 : 14 . 55,而不是00 : 14 . 57

这是我当前计时器的一个JSFiddle。我认为这个问题很可能发生在stopwatch.js文件中,但是我不知道为什么会这样,因为我正在使用Date.now()来计算已经过去了多少时间。下面是stopwatch.js文件,它是单个秒表的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Stopwatch {
  constructor (opts) {
    this.isOn = false;
    this.time = 0;
    this.elem = opts.elem;
  }

  start () {
    this.offset = Date.now();
    this.interval = setInterval(() => this._update(), 10);
    this.isOn = true;
  }

  stop () {
    clearInterval(this.interval);
    this.offset = null;
    this.interval = null;
    this.isOn = false;
  }

  reset () {
    this.time = 0;
    this._render();
  }

  _update () {
    this.time += this._getTimePassed();
    this._render();
  }

  _getTimePassed () {
    const now = Date.now();
    const timePassed = now - this.offset;
    this.offset = now;
    return timePassed;
  }

  _timeFormatter (milliseconds) {
    const padZero = (time) => `0${time}`.slice(-2);

    const minutes = padZero(milliseconds / 60000 | 0);
    const seconds = padZero((milliseconds / 1000 | 0) % 60);
    const centiseconds = padZero((milliseconds / 10 | 0) % 100);

    return `${minutes} : ${seconds} . ${centiseconds}`;
  }

  _render () {
    this.elem.textContent = this._timeFormatter(this.time);
  }
}

我在上面提到的JSFiddle中包含了所有东西,如果读起来更容易的话,在这个要旨中也是如此。如有任何指导,将不胜感激。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-07-12 19:59:31

你说的是20毫秒的延迟,这可能是由许多因素造成的。

  • 正如Flynn1179所建议的,可能在对Date.now()的调用之间
  • JavaScript的setInterval漂移!这是用来证明这一点的垃圾桶。对于在单个线程上运行的语言来说,您不可能期望每10‘t精确地安排任务一次,而您的_update方法正是这样要求的。
  • 您忽略了厘米计数器中的0-9ms,这是在主计时器中计算的。这可能是最大的促成因素。例如,假设迷你表A为15毫秒,微型表B为15毫秒。迷你表A将显示'01',微型手表B将显示'01',但主表将显示'03‘自30毫秒已过。

为了正确地解决这个问题,我建议重新设计您的解决方案,以便将所有秒表封装在一个StopwatchManager中,它同时呈现所有秒表,并通过添加迷你表的时间来计算主表的总时间。您可能还需要研究如何使用requestAnimationFrame来呈现而不是setInterval

票数 5
EN

Stack Overflow用户

发布于 2016-07-09 17:09:38

你停止一个计时器,在下一行,开始下一个计时器。您的问题部分在于,时间在这两个方法调用之间传递。

而且,您的“停止”方法甚至不使用当前时间,它只是追溯地从上次更新时停止它,它不会执行最终的_update

如果您真的希望它精确地加起来,那么在您的updateMiniTimers方法中使用updateMiniTimers,并将它传递给两个调用,以确保它们在同一时间点停止/启动,并在stop调用之后执行最终呈现。

一般而言,在方法范围内:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
method() {
  var a = Date.now();
  var b = Date.now();
}

A和b绝对不能保证是相同的,没有任何方法调用是瞬时的。

票数 1
EN

Stack Overflow用户

发布于 2016-07-18 08:06:30

我同意法拉兹关于可能的原因的看法。我还将检查各司的舍入错误。无论如何,如果您想使它更健壮和可扩展,您可以将您的时间点看作列表中不断扩展的元素。每当秒表启动时,您都会将列表中最后一个元素的索引记录为起始点,当结束时将最后一个元素的索引记录为终结点。这将允许您拥有精确的定时器层次结构。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38287667

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文