Spot the bug - #162: Task Runner Queue

Tricky closure bug lurking in this delayed queue processor.

function runTasks(tasks, delay) {
  for (var i = 0; i < tasks.length; i++) {
    setTimeout(function() {
      tasks[i]();
    }, delay * i);
  }
}

Reply with what is broken and how you would fix it.

The i variable is the problem here. When setTimeout finally runs, the loop is already finished. So i is always the last value. You can fix this by changing var i to let i. let creates a new i for each loop turn, so the closure works correctly.

function runTasks(tasks, delay) {
  for (let i = 0; i < tasks.length; i++) {
    setTimeout(function() {
      tasks[i]();
    }, delay * i);
  }
}