Ускорить setInterval

Я знаю, что в методе setInterval в javascript существует минимум 1 миллисекунда. Могу ли я ускорить это? Как использовать микросекунды?

для чего мне это нужно:

Я создаю анимацию canvas css/js. это простая линия, которая изгибается и возвращается к линии. У меня есть ползунок для регулировки скорости этой анимации. поэтому минимальное значение слайдера будет очень быстрым, а самое высокое - очень медленным. это понятно? спасибо!

Ответ 1

Обновление:

Обратите внимание, что когда этот ответ был написан, вопрос был:

Я знаю там минимум 1 миллисекунду в методе setInterval в JavaScript. Могу ли я ускорить это? Как использовать микросекунды?

Позже он был отредактирован, чтобы включить информацию о анимации холста, и с этой новой информацией правильный ответ будет использовать метод window.requestAnimationFrame:

function step(timestamp) {
  // do something for every frame
  window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);

Обратный вызов step получает метку DOMHighResTimeStamp с точностью до 1 микросекунды в качестве аргумента при каждом вызове, что каждый раз, когда экран обновляется (нет необходимости рисовать что-либо более часто, потому что оно не будет отображаться в любом случае).

Первоначально вопрос касался ускорения метода setInterval, и мой первоначальный ответ заключался в том, чтобы делать что-либо вообще чаще, чем минимальная задержка setInterval позволяет (что составляет 4 мс для уровней вложенности больше 5 в соответствии с спецификацией WHATWG, раздел 8.4 Timers или 4ms для уровней вложенности 4 или выше в соответствии с этот пост Джеймса Робинсона, и исторически он работал по-разному).

Оригинальный ответ:

Я действительно не знаю, что вы пытаетесь сделать, я могу только говорить из опыта того, что люди обычно хотят с этим делать.

Если вы хотите вызвать setInterval с использованием микросекунд, тогда код, который вы хотите запустить, должен принимать значительно меньше миллисекунды, иначе он не будет иметь смысла в однопоточном цикле событий.

Вам не нужно беспокоиться о блокировке браузера в течение нескольких минут, поэтому я бы предложил использовать что-то вроде этого: вместо

setInterval(function () {
    // YOUR CODE
}, 1/100);

Попробуйте сделать:

setInterval(function () {
    for (var i = 0; i < 1000; i++) {
        // YOUR CODE
    }
}, 10);

Фактически вы сделаете свой код более эффективным, избегая переадресации вызовов обратного вызова и с более длинными интервалами ваш код будет работать более предсказуемо.

Также никто не заметит, что ваш код работает в пакетах 1000 раз каждые 1/100 секунды, потому что есть вероятность, что сам браузер уже запускается в таких пакетах благодаря планированию процесса на уровне ОС, а также экран все равно не будет обновляться быстрее.

Эксперимент

Хорошо, теперь какой-то эксперимент. Попробуйте этот код, чтобы узнать, что на самом деле является самым коротким интервалом для вашего браузера:

var start = new Date();
var i = 0, interval = setInterval(function(){
    if (++i >= 1000) {
        var end = new Date();
        alert("The average interval was "
              + ((end-start)/1000)) + " milliseconds";
        clearInterval(interval);
    }
}, 0);

Обратите внимание, что он даже не будет согласован в одном браузере. Это зависит от вашей загрузки системы, например.

Проверьте свой браузер

Попробуйте ЭТО FIDDLE, чтобы проверить свой браузер и опубликовать свой результат в комментариях, если хотите. Интересно, какой будет запись.

Ответ 2

Обратите внимание, что некоторые браузеры не будут принимать интервалы, меньшие, чем 50 миллисекунд. Если вы пройдете меньший интервал, они будут использовать наименьшее из них, которое они могут использовать.

Ответ 4

FYI, будет бесполезно делать это менее чем за несколько миллисекунд между каждым интервалом, потому что canvas ops занимает несколько миллисекунд, чтобы делать свою собственную вещь, одновременно блокируя ваш основной цикл (однопоточный). Выполнение 1/100 в миллисекундах фактически округляется до 16 в классических браузерах и 5 миллисекунд в хроме.

Вы делаете это неправильно, если вы пытаетесь настроить время анимации в javascript на микросекунды, потому что это бесполезная цель. сбор мусора, временная дисперсия занятой петли повредит вам, не говоря уже о том, что вы слишком быстро рисуете, вы можете разорвать раму.

РЕШЕНИЕ: используйте requestAnimationFrame, чтобы получить максимальный FPS из браузера и не забудьте предоставить резервную копию setInterval (..., 16).

https://developer.mozilla.org/en/DOM/window.mozRequestAnimationFrame http://dev.chromium.org/developers/design-documents/requestanimationframe-implementation

Ответ 5

Я знаю, что это старый вопрос, но он все еще не имеет принятого ответа.

Вам не нужно иметь более короткий интервал, чтобы увеличить скорость, с которой ваша линия будет согнута. Вы сохраняете интервал один и тот же, это ваша частота кадров, и вы просто меняете шаг между состояниями линии. Он изгибается больше между кадрами, если он быстро изгибается.

Вот пример из того, с которым я играл.

var radius = 0;
var hor = 0;
var frameTime = 1000/60;
var step = 1;

setInterval(function () {
    var draw = document.getElementById('draw');
    var context = draw.getContext('2d');

    draw.width = draw.width;

    context.fillStyle = '#ffffff';
    context.beginPath();
    context.arc(draw.width/2,draw.height/2,radius,0,Math.PI*2,true);
    context.closePath();
    context.stroke();
    context.fill();

    radius = (radius+(step*frameTime))%(draw.height/2);
}, frameTime);

Это очень простая анимация, только круг, который растет до размера холста, а затем возвращается из ничего. Здесь переменная "step" управляет скоростью анимации. "frameTime" - это время между кадрами.

Надеюсь, я правильно понял, в чем проблема. Я знаю, что вы, наверное, давно это пережили, но я подумал, что лучше всего получить ответ здесь для тех, у кого есть аналогичная проблема в будущем.

Ответ 6

Я не уверен, что это сработает, но попробуйте погрузиться в миллисекунду, чтобы сломать ее дальше. например.

setTimeout ( "moretext()", 1/100);