Creating Infinite Iterators

Iterators in JavaScript are inherently lazy. They yield a value, wait for it to be consumed by the caller, and then, when requested for more, go on to produce the next value. While we can yield values from a known collection of data, we can also exploit this flexibility to create infinite sequences of data.

As an example, let’s create an infinite sequence of prime numbers. As a first step, we’ll define an isPrime() function that will tell us whether a given number is a prime number.

 const​ isPrime = ​function​(number) {
 for​(​let​ i = 2; i < number; i++) {
 if​(number % i === 0) ​return​ ​false​;
  }
 
 return​ number > 1;
 };

The isPrime() function is a rather rudimentary implementation that determines if any number greater than 1 is a prime number—our purpose is not to optimize that function but to create an infinite series, so we’ll keep our focus on that. Let’s use this function to create a generator, like so:

 const​ primesStartingFrom = ​function​*(start) {
 let​ index = start;
 
 while​(​true​) {
 if​(isPrime(index)) ​yield​ index;
  index++;
  }
 };

The variable primesStartingFrom refers to an anonymous generator function—we use * after the function keyword to define this function as a generator. Within the function we have an infinite loop that yields prime numbers, starting from the given start value, one at a time, forever. The generated sequence is infinite, but where would we store it? On the cloud of course!

The key idea here is laziness. Within the loop, when the flow of execution meets the call to yield, the control transfers to the caller side of the iteration immediately. If and only when the iteration returns to the iterator function, the index value is incremented and the while loop takes the next iterative step.

Let’s now use the generator in an iteration. The sequence is infinite, but on the calling side, we have to control how many values the generator will yield—we can break out of the iteration whenever we like; for example:

 for​(​const​ number ​of​ primesStartingFrom(10)) {
  process.stdout.write(number + ​', '​);
 if​(number > 25) ​break​;
 }

The for loop iterates over the values returned by the generator, but it breaks out of the loop when number is greater than 25, thus terminating the iteration. Let’s run the code and take a look at the output generated:

 11, 13, 17, 19, 23, 29,

The generator produces 11 as the first prime number and proceeds to produce the sequence of prime numbers that follow, one at a time, until we break out of the loop when the value received is greater than the threshold we set.

The ability to easily create an infinite sequence is quite useful. We don’t have to eagerly compute results a priori. Computation may be postponed for evaluation until the results are actually needed. That, in turn, can make the execution of code more efficient.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset