Почему setInterval быстрее?

174
28 декабря 2018, 15:40

Есть два бегуна:

var runner1 = new Runner();
var runner2 = new Runner();

У каждого есть метод step(), который делает шаг, увеличивая свойство steps.

Конкретный код метода step() не имеет значения, важно лишь что шаг делается не мгновенно, он требует небольшого времени.

Если запустить первого бегуна через setInterval, а второго – через вложенный setTimeout – какой сделает больше шагов за 5 секунд?

function Runner() {
  this.steps = 0;
  this.step = function() {
    this.doSomethingHeavy();
    this.steps++;
  };
  function fib(n) {
    return n <= 1 ? n : fib(n - 1) + fib(n - 2);
  }
  this.doSomethingHeavy = function() {
    for (var i = 0; i < 25; i++) {
      this[i] = fib(i);
    }
  };
}
var runner1 = new Runner();
var runner2 = new Runner();
// запускаем бегунов
var t1 = setInterval(function() {
  runner1.step();
}, 15);
var t2 = setTimeout(function go() {
  runner2.step();
  t2 = setTimeout(go, 15);
}, 15);
// кто сделает больше шагов?
setTimeout(function() {
  clearInterval(t1);
  clearTimeout(t2);
  alert( runner1.steps );
  alert( runner2.steps );
}, 5000);

Про работу методов setTimeout() рекурсивного и setInterval() в разных браузерах мне всё понятно. Не понятно одно:в данном коде при вызове рекурсивного setTimeout(в силу его специфики: фиксированной паузы между вызовами) срабатывает функция doSomethingHeavy(), а при вызове метода setInterval, эта функция не срабатывает сразу идёт подсчёт шагов,вызовы идут равномерно один за другим. Именно поэтому setInterval быстрее?