Skip to content

Instantly share code, notes, and snippets.

@rauschma
Last active November 24, 2020 07:14
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Embed
What would you like to do?

for-of, early termination, iterators, and generators

If we terminate a loop early, for-of invokes method .return() of the iterator. Generators return generator objects (that implement both the Iterable interface and the Iterator interface). If we invoke .return() on such an object, the generator is terminated. We can prevent that by overriding .return().

More information: https://exploringjs.com/es6/ch_iteration.html#sec_iteration-protocol-in-depth

Demonstration:

function logIter(iter) {
  console.log('------');
  // First element
  for (const x of iter) {
    console.log(x);
    break;
  }
  // Remaining elements
  for (const x of iter) {
    console.log(x);
  }  
}

//========== .return() stops execution of generator

function* generator1() {
  yield 'a';
  yield 'b';
  yield 'c';
}
const iter1 = generator1();
logIter(iter1);

//========== Overriding .return() so that generator keeps on going

function* generator2() {
  yield 'd';
  yield 'e';
  yield 'f';
}
const iter2 = generator2();
iter2.return = () => {
  console.log('RETURN');
  // Result is only used by yield*
  return {};
};
logIter(iter2);

//========== Array iterators are not affected by .return()

const arr = ['g', 'h', 'i'];
const iter3 = arr[Symbol.iterator]();
logIter(iter3);

//========== Output
// '------'
// 'a'
// '------'
// 'd'
// 'RETURN'
// 'e'
// 'f'
// '------'
// 'g'
// 'h'
// 'i'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment