如何在React Native中使计时器计时并精确显示时间?

时间:2019-04-15 02:18:34

标签: javascript react-native timer

编辑:

在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

}

逻辑是正确的(但看起来也有些丑陋,如果有更好的方法,我会很感激)。

我使用间隔的方式是useInterval hook

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 个答案:

答案 0 :(得分:0)

我找到了解决计时器问题的方法。

我实现了Yossi的想法,并且可行!

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

我还就如何在javascript中做到这一点做了一个article

Here是ReactJs中的实现,与React Native相同,您只需要更改其呈现的内容即可。

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

谢谢尤西!