How does yield * work in Javascript?

7

Many times, when I have a question that I'm sure has already been answered, I come here in "Ask a question" and I type the terms that I think are key in the title, to get the related answers. But I did not find any when I typed this one.

I saw in some code snippets the keyword yield* . Is it different from yield ?

Searching on, I came up with the following code example:

function* g1() {
  yield 2;
  yield 3;
  yield 4;
}

What is the reason for * next to the keyword function ? Does it have to do with the * next to yield ?

    
asked by anonymous 22.03.2017 / 12:35

1 answer

14

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.

    
22.03.2017 / 13:54