2017-02-07 3 views
3

Я строю метроном в React Native. После нажатия на кнопку, я установил setTimeout для следующего щелчка. Сроки, однако, ужасны.Точность setTimeout in React Native

я сделал следующий быстрый тест:

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

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

В идеале, я должен получить 0 в консоли. При запуске этого внешнего React Native в Chrome Dev Tools я получаю -1, иногда -2 (мс). Это приемлемый результат.

Запуск этого внутри React Native с использованием Simulator на macOS. Я получаю значения от 0 до -100. Это явно неприемлемо.

Кто-нибудь знает, связано ли это с неточностями setTimeout или неточностями (new Date()).getTime()? Могу ли я это исправить?

ответ

1

Я исследовал практически любые решения 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 только, конечно.

+0

У меня был такой же опыт, используя неродный код. Наклейка на нативный код на самом деле является единственным решением на данный момент. –

2

Задержка, которую вы настраиваете для setTimeout и setInterval, никогда не должна рассматриваться как точное время задержки. Они представляют собой «минимальное» количество времени, которое вы будете ждать до выполнения функции. Это связано с тем, что пользователь-агент помещает обратный вызов в очередь событий по истечении времени, но если пользователь-агент все еще работает над какой-либо другой задачей, там будет выполняться обратный вызов.

Вы также должны знать, что существует встроенное абсолютное минимальное время, которое вы никогда не сможете преодолеть примерно в 9-14 м. Это происходит из-за внутренних компонентов пользовательского агента.

+1

Не говоря уже о том, что большинство устройств используют тактовую частоту 60 Гц для отслеживания текущего времени, поэтому конструкции типа 'new Date()' могут быть отключены на 16 мс. Если вам нужна более высокая точность, вам нужно использовать таймер с высоким разрешением для измерения тактовой частоты. Это будет [performance.now()] (https://developers.google.com/web/updates/2012/08/When-milliseconds-are-not-enough-performance-now). – Brandon

+0

Убрать ответ, спасибо! Как бы кто-то осуществил метроном тогда ... (или любое другое приложение, которое нуждается в точном времени)? –

+0

Как упоминал Брэндон выше, посмотрите на performance.now(). –