2013-10-06 5 views
1

Я использую node.js, но этот вопрос строго связан с javascript. Я взаимодействую с платой i2c, чтобы угасать огни, и я хотел бы их постепенно погасить, скажем, 1 секунду. Теперь с setInterval, в теории она должна работать как ... если бы я хотел, чтобы исчезнуть их 100 шагов в 1 секунду я мог бы просто сделать что-то вроде ...Временные функции javascript с setInterval

var fader = setInterval(function(){ 
//will fade light 100 steps in 1 second 
    doFade(something,something); 
},10) 

Но в зависимости от кода внутри цикла интервала , это может занять больше 1 секунды (я тестировал и для моего приложения было около 2,5 секунд). Я уверен, что факт, что функция doFade занимает определенное количество времени, является причиной этой проблемы, но мне просто интересно, есть ли какой-либо реальный способ сделать это на самом деле, все произойдет в течение 1 секунды.

+0

как делает 'doFade' функция выглядит? – lukaleli

+1

Вместо того, чтобы предполагать, что временной интервал является постоянным 1/100th секунды, проверьте часы на каждой итерации и посмотрите, насколько далеко вы на самом деле находитесь. – Pointy

+0

@jimmyweb это в основном сообщение с устройством по протоколу i2c. он выполняет 6 вычислений, хиты 2 других функций записывает 4 байта в устройство i2c. –

ответ

2

Ближайшим вы когда-нибудь, AFAIK, полагаясь исключительно на JS бы сделать что-то вроде этого:

var fader = (function(now) 
{ 
    var timeLeft, end = now + 1000,//aim for 1000 ms 
     stepsRemaining = 100, 
     callBack = function() 
     {//define here, avoid redefining function objects 
      doSomething(foo, bar); 
      setter(); 
     }, 
     setter = function() 
     {//recompute interval, set anew 
      if (stepsRemaining <= 0) 
      {//avoid infinite timeouts 
       return; 
      } 
      timeLeft = (end - (+(new Date))); 
      timeLeft= timeLeft > 0 ? timeLeft : 0;//ensure positive timeleft, if not, 0 intervals ==> ASAP 
      fader = setInterval(
       callback, 
       Math.floor(
        timeLeft/stepsRemaining-- 
       ) 
      ); 
     }; 
    setter(); 
    return fader; 
}(+(new Date)));//get ms now 

Этот код, хотя непроверенные создает все функции объекты заранее. Затем, используя setter, каждый раз, когда интервал заканчивается, пока вы не установили 100 интервалов, будет вычислен новый интервал. После выполнения работы, с помощью функции callBack, setter вызывается снова. Здесь проверяется количество оставшихся шагов, затем timeLeft вычисляется снова и на основе остальных шагов, которые уменьшаются на 1 при каждом вызове до setter.
Чтобы избежать установки интервалов слишком долго, или с использованием флоат-номера, я звоню Math.floor и избегать установления отрицательных значений тайм-аута, я проверяю стоимости timeLeft тоже, очевидно

Смежные вопросы