Если вы используете setTimeout()
быстро поддаться браузер так что поток пользовательского интерфейса может догнать с любыми задачами, которые необходимо выполнить (например, обновлением вкладки или отсутствием диалогового окна Long Running Script), существует новый API под названием Efficient Script Yielding, aka, setImmediate()
, который может работать немного лучше для вас.
setImmediate()
работает очень похоже на setTimeout()
, но он может работать сразу, если браузеру больше нечего делать. Во многих ситуациях, когда вы используете setTimeout(..., 16)
или setTimeout(..., 4)
или setTimeout(..., 0)
(т. Е. Вы хотите, чтобы браузер выполнял все выдающиеся задачи потока пользовательского интерфейса и не отображал диалоговое окно с длинным запуском сценария), вы можете просто заменить setTimeout()
на setImmediate()
, отбросив вторую (миллисекунду) аргумент.
Разница с setImmediate()
заключается в том, что это в основном выход; если браузер когда-нибудь сделает что-то в потоке пользовательского интерфейса (например, обновит вкладку), он сделает это, прежде чем вернуться к вашему обратному вызову. Тем не менее, если браузер уже успел завершить работу, обратный вызов, указанный в setImmediate()
, будет выполняться без задержки.
К сожалению, он поддерживается только в IE9 +, так как есть push back от других производителей браузеров.
Возможно, имеется good polyfill, если вы хотите использовать его и надеетесь, что другие браузеры его реализуют в какой-то момент.
Если вы используете setTimeout()
для анимации, requestAnimationFrame ваш лучший выбор, как ваш код будет работать в синхронизации с частотой обновления монитора.
Если вы используете setTimeout()
на более медленной каденции, например. один раз каждые 300 миллисекунд, вы можете использовать решение, аналогичное тому, что предлагает пользователь1213320, где вы отслеживаете, сколько времени прошло с последней отметки времени вашего таймера, и компенсировать любую задержку. Одно из усовершенствований заключается в том, что вы можете использовать новый интерфейс High Resolution Time (aka window.performance.now()
) вместо Date.now()
, чтобы получить разрешение больше, чем миллисекунды на текущее время.
Было бы здорово увидеть пример этого. – backdesk 2012-03-14 15:45:22
Как насчет вызова setTimeout() от рабочего. Разве это не уменьшит блокировку, вызванную рендерингом? – hidarikani 2014-11-17 15:49:19
Нет никакой гарантии, что @hidarikani. FWIW, это может быть такой же проблемой в собственном коде, и в браузере у вас нет возможности требовать таймеры с высоким разрешением и задержки в реальном времени. Не то, чтобы вы хотели; это рецепт для потери CPU, и вы должны предположить, что, по крайней мере, в некоторых случаях браузер и ОС будут делать все возможное, чтобы сохранить время автономной работы и принести в жертву вашу точность таймера для этой цели. – Shog9 2014-11-17 20:31:13