【问题标题】:How to make a timer that ticks and display time at an exactly interval in React Native?如何在 React Native 中制作一个以精确间隔计时并显示时间的计时器?
【发布时间】:2021-05-22 01:14:27
【问题描述】:

编辑:

在 RN 中,setInterval 不会完全处于您想要的间隔。有时需要更长的时间

如何实现一个计时器,以您提供的时间间隔(例如 100 毫秒)精确计时并显示时间

计时器的计时方式应与手机自带的本地计时器相同。

*下面这点是我试图做的,但可以忽略或用它来解决


背景:

我正在做一个计时器。为了在屏幕上显示它,我制作了一个如下所示的对象
例如

let time = {
    milliseconds: 1,
    seconds: 2,
    minutes: 3
}

我有一个setInterval,它从这个对象中减去x 毫秒。

我想要做什么:

我需要从这个对象中减去毫秒的最快和最佳方法。遵循正常时间规则(1000 毫秒为 1 秒,60 秒为 1 分钟),如果您得到负时间,它还需要在 0 处停止。
它应该感觉像一个原生计时器。

我尝试过的:

这是我用来从计时器对象中减去毫秒的函数:

export function minusTime(time, millis) {

    let milliseconds = parseInt(millis % 1000)
    let seconds = Math.floor((millis / 1000) % 60)
    let minutes = Math.floor((millis / (1000 * 60)))

    if (time.minutes - minutes < 0) {
        return -1
    }
    time.minutes -= minutes
    if (time.seconds - seconds < 0) {
        if (time.minutes - 1 < 0) {
            return -1
        } else {
            time.minutes -= 1
            time.seconds += 60
        }
    }
    time.seconds -= seconds
    if (time.milliseconds - milliseconds < 0) {
        if (time.seconds - 1 < 0) {
            if (time.minutes - 1 < 0) {
                return -1
            } else {
                time.minutes -= 1
                time.seconds += 59
                time.milliseconds += 1000
            }
        } else {
            time.seconds -= 1
            time.milliseconds += 1000
        }
    }
    time.milliseconds -= milliseconds
    return time

}

逻辑是正确的(但也有点难看,如果有更好的方法,我很感激)。

我使用区间的方式是这个useIntervalhook

function useInterval(callback, delay) {
    const savedCallback = useRef()

    // Remember the latest callback.
    useEffect(() => {
        savedCallback.current = callback
    }, [callback])

    // Set up the interval.
    useEffect(() => {
        function tick() {
            savedCallback.current()
        }
        if (delay !== null) {
            let id = setInterval(tick, delay)
            return () => clearInterval(id)
        }
    }, [delay])
}

在我的组件中,我称之为

useInterval(() => {
        ...
        let blockTime = minusTime(currentBlock.blockTime, interval)
        ...
}, isRunning ? interval : null)

我只是把它显示出来

<Text>                            
    {`${minutes}:${seconds},${milliseconds}`}
</Text>

问题:

当我运行它时,我的计时器中的 1 秒不是现实生活中的 1 秒。

我怎样才能让它成为现实生活中的 1 秒?我的功能是否需要很长时间才能运行,这就是为什么它很慢?还是我需要别的东西?

如何执行我的计时器,使其与现实生活中的 1 秒匹配?
有没有更好的方法来处理我的计时器对象?

【问题讨论】:

  • 不确定为什么会有差异,但计算起来确实很尴尬。为什么不将时间仅以毫秒为单位,如果您需要知道执行简单计算的分钟和秒数?
  • 关于时间没有正确测量,如何保存,每次触发计时器时,以毫秒为单位的当前时间,使用new Date().getTime(),以及下一个计时器设置为,并且当计时器为 0 时 console.log 所有值。
  • 刚刚编辑了我的问题,以便更清楚地关注预期结果
  • 我不知道,对不起...

标签: javascript react-native timer


【解决方案1】:

我找到了一种方法来为计时器解决这个问题。

我实现了Yossi 的想法,它成功了!

他的想法(或我对它的理解)是计算setInverval 运行的实时时间,而不是提供给setInterval 的时间间隔。您需要跟踪间隔之间的时间。

我还发了一个article 来讨论如何在 javascript 中执行此操作。

Here是ReactJs中的实现,React Native也是一样的,你只需要改变它渲染的内容。

我还在我的 React Native 计时器中对此进行了测试,以检查此策略是否有效,是的,它有效。

谢谢尤西!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-16
    • 2012-10-17
    • 2017-05-08
    • 2017-10-12
    • 1970-01-01
    相关资源
    最近更新 更多