Iterators & Generators

Iterators & Generators

Iterable protocol

Protocol characteristics

The

“Iterable protocol” is an agreed-upon APi at the level of JavaScript as a language, for creating objects that can be used to iterate over a collection of data. The key characteristic of this protocol is “sequentiality” ie. property that when iterating, it returns the value of the iterable structure one by one. Data types that satisfy the iterable protocol are called “iterable collections”. Respecting the iterable protocol, it is necessary that the function returns an object containing a special method “next()”.

next()

When called, the next() method returns a member of the collection temporarily “wrapped” (eng. wrapped”) with an object that has two properties: value and done. As long as there are members for iteration, the method returns the value of the “done” property as “false”, and only when the iteration “comes” to the end, the “done” property is defined as “true”.

Example

Through the following example, the concept of the protocol:

is described

Which data types are iterable?

It should be emphasized that ordinary javascript objects are not iterable, but the following data types satisfy the iterable protocol:

  • String
  • Array
  • Array-like arguments or NodeList object
  • TypedArray
  • Map
  • Set

Which mechanisms in JavaScript require an iterable collection?

Mechanisms for the use of which “iterable” collections are necessary are:

  • Destructuring
  • for..of loop
  • Array.from()
  • Spread operator ()
  • Maps & Sets
  • Promise.all(), Promise.race()
  • yield*
Example

Iterable collections can use mechanisms that require iterable collections such as iteration with a “for..of” loop:

or when destructing:

Iterable and Iterator

Creating an iterator with an iterable object

To create an iterator, the object needs to have a specific internal method that returns an iterator, whose key is “Symbol.iterator”. Such an object is called an “Iterable object”.

Iterator object is created by calling the iterable object method named: “[Symbol.iterator]( )”.

iterator

Definition

Iterator is an object, which knows how to access the members of the iterable collection, one by one and contains a pointer that points to the next element. The iterator object is provided by “next()” method, which returns a “wrapped” collection member with an object that has two properties: value and done.

Example

As you can see from the previous example, the property “done” signals when the iteration has come to an end.

Application of Iterable and Iterator

Thanks to the iterator and the next() method, iteration through the iterable collection for for..of loop is enabled:

Generator function and Generators

Marking the generator function

A generator function is a special type of function that is denoted as follows:

A generator function can also be defined as a object method:

or even as a class method:

Characteristics of the generator function

The generator function acts as a “factory” for specific so-called iterators. generators, and in addition it can pause its work with the keyword “yield”. When the compiler “runs into” the “yield” keyword during the execution of the function, it pauses the further execution of the function and returns a generator object that was created according to the “iterable protocol” (iterable). The keyword “yield” is allowed to be used only within the generator. To continue the execution of the generator function, the iterator method “next()” is applied.

generator

Generators

generators

Generator is a specific type of iterator, which is created by calling the generator function. The generator function generates an iterable dataset, so we can use the next() method as well as the “for..of” loop to iterate. The differences between a “regular” iterator and a generator are:

  • with the generator, the method can receive a parameter gen.next(value)
  • there is an additional method throw()

As with iterators, the “next()” method returns a collection member “wrapped” with an object that has two properties: value and done. The value of the property can be obtained directly from yield or as the returned value of the generator parameter. The “yield” keyword always returns some value even if it is null.

“Generators have a built-in communication channel with yield”

Example

In this example, after the execution of the first line, the keyword “yield” pauses further execution of the function. To continue the function, the “next()” method is used, after which the method returns the next member of the “wrapped” collection with an object that has two properties: value and done.

Thanks to the feature of the generator function that can be paused during execution and then continue execution, only with generators and generator functions it is possible to stop the execution of one function, start another that returns a value, and send that value back through a parameter to the first function and continue execution.

Example

Example

Thanks to the possibility that a function can stop its execution, we can then call another function as in this example: