October 2, 2015

Reusing an ES6 iterator? Not quite

One you’ve called iterator.next() on an array iterator enough times to make it return the last item with the property done set to true, you can’t make it go back to the first item. But you can grab a new iterator for the same array. I was surprised to find out in the node.js REPL that:

var users = ["steve", "bob", "jill"];
users[Symbol.iterator]() === users[Symbol.iterator]();
false;

The two iterators retrieved are actually 2 different iterators. No need to shallow copy the array to get another iterator. I have a scenario where I want to loop through an array of users of a blogging service and retrieve their RSS feeds every one in a while. This will work:

var users = ["steve", "bob", "jill"];
var userIterator = users[Symbol.iterator]();

function oneIteration() {
  var nextItem = userIterator.next();

  if (nextItem.done) {
    userIterator = users[Symbol.iterator]();
    nextItem = userIterator.next();
  }

  // get the rss feed, or just print out the user's name for this example
  console.log(nextItem.value);

  // retrieve the next feed after some amount of time
  setTimeout(oneIteration, 5000);
}

oneIteration();

The iterator can take the place of a userIndex variable that is incremented with each RSS fetch, and reset to 0 at the end of the array. Whether this is better or worse is up to you.