Generators
The function*
syntax is used to define a generator and yield
is the analog to return
for a generator.
What is it?
Generator is considered as a special function, responsible for creating an iterator. It is characterized by calculating each item belonging to the iterable element at a time, rather than storing them all in memory, as is done without the generator. This feature is known as lazy evaluation .
Example
Consider the Fibonacci sequence, that each element consists of the sum of the two previous elements. Without using a generator, we could do:
function fibonacci (n)
{
var sequence = [];
sequence.push(0, 1);
for (let i = 2; i < n; i++)
{
sequence.push(sequence[i-1] + sequence[i-2]);
}
return sequence;
}
const sequence = fibonacci(10);
console.log(sequence.length);
The above code will generate an output equal to 10, referring to the number of positions stored in memory for the sequence. For small amounts, this would not affect the application, but if we consider a gigantic value, such as a million elements, this would probably affect the performance of your application.
Using the generator:
function* fibonacci (n)
{
var a = 0, b = 1, current;
while (true)
{
current = a;
yield current;
a = b;
b = current + b;
}
}
const sequence = fibonacci(10);
for (let i = 0; i < 10; i++)
{
console.log(sequence.next().value);
}
List elements will not be in memory when we make const sequence = fibonacci(10)
, they will be computed within for
, only when they are used, through sequence.next()
. But what if the list needs to have a million elements? No problem, as the elements are not in memory, the generator will not affect your application (runtime would still be high, because millions of operations would continue to run, but in memory, it would not be affected).
Iterator
The return of a generator is a iterator and, therefore, implements the next
method.
Utilization
ImaginethatyouwanttodisplayalistofallBraziliancitynames,whichnumberapproximately5570,usinginfinitescroll.Storingthedataofthese5570recordsinmemorywouldbeunnecessary,astheuserwillhardlyusethemall.Thenyoucoulddisplayaninitialamount,20forexample,andwhentheuserrequiresmore,whenreachingtheendofthelist,make,withthegenerator,anAJAXrequesttotheserverrequesting10morerecordsandaddingthemtothelist.Thisway,the5570recordswouldonlybeinmemoryiftheuserrequestedit.
Related
The Fibonacci sequence, although not widely used in practice, was used as an example because of ease of implementation.