【问题标题】:Accuracy of setTimeout in React NativeReact Native 中 setTimeout 的准确性
【发布时间】:2017-02-07 21:48:20
【问题描述】:

我正在用 React Native 构建节拍器。播放一次点击后,我为下一次点击设置了setTimeout。然而,时机很糟糕。

我做了以下快速测试:

let time = (new Date()).getTime() + 50;

setTimeout(() => {
  console.log(time - (new Date()).getTime());
}, 50)

理想情况下,我应该在控制台中得到 0。在 Chrome 开发工具中在 React Native 之外运行它时,我得到 -1,有时是 -2(毫秒)。这是可以接受的结果。

在 macOS 上使用模拟器在 React Native 中运行它,我得到介于 0 和 -100 之间的值。这显然是不可接受的。

有人知道这是因为setTimeout 的不准确还是(new Date()).getTime() 的不准确?我可以解决这个问题吗?

【问题讨论】:

    标签: javascript reactjs react-native settimeout


    【解决方案1】:

    您为setTimeoutsetInterval 配置的延迟不应被视为确切的延迟时间。它们代表在执行函数之前您将等待的“最短”时间。这是因为用户代理在时间过去后将回调放入事件队列,但如果用户代理仍在处理其他任务,回调将坐在那里。

    您还应该知道,您永远无法低于的内置绝对最短时间大约为 9-14 毫秒。这是由于用户代理的内部结构造成的。

    【讨论】:

    • 更不用说,大多数设备使用 60Hz 时钟来跟踪当前时间,所以像 new Date() 这样的结构可以关闭多达 16 毫秒。如果您需要更高的精度,则需要使用高分辨率计时器来测量时钟增量。那将是performance.now()
    • 明确答复,谢谢!那么有人将如何实现节拍器......(或任何其他需要精确计时的应用程序)?
    • performance.now() 解决了获取准确时间的问题。但是,使用 performance.now() 无法设置准确的超时,是吗?这可能是一个不可修复的问题,因为 React Native 在单个线程上运行。一个快速的谷歌将我指向hamsters.io,这有帮助吗?
    • 更新:performance.now() 在 React Native 中不可用,并且 hamster.io 不适用于 iOS 上的 React Native。
    • 我不太确定这样的事情是否可以通过客户端代码完成。它可能必须是可下载的应用程序。
    【解决方案2】:

    我研究了几乎所有用于播放音频的 React Native 解决方案以及使用 javascript setTimeout()/setInterval() 的各种方法,但在时间稳定性和准确性方面都不能令人满意。

    目前可能唯一的方法是将一些像这样的本机模块:https://developer.apple.com/library/content/samplecode/HelloMetronome/Introduction/Intro.html 粘贴到 js 端,如 RN Docs 中所述:https://facebook.github.io/react-native/docs/native-modules-ios.html,这给出了相当不错的结果,但不幸的是,它是 iOS只是,当然。

    【讨论】:

    • 我在使用非本地代码时也有同样的经历。粘合原生代码确实是目前唯一的解决方案。
    猜你喜欢
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2018-07-06
    • 2023-04-05
    • 2019-11-27
    • 1970-01-01
    • 1970-01-01
    • 2018-12-12
    相关资源
    最近更新 更多