How does Yield* work in Javascript?

Asked

Viewed 2,677 times

10

I saw in some code snippets the keyword yield*. She is different from yield?

Researching on, I came to the following example of code:

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

What does the * beside the keyword function? It has to do with the * next to yield?

1 answer

25


Generators

The syntax function* is used to define a generator and yield is the analogue to return for a generator.

What is?

Generator is considered as a special function, responsible for creating an iterator. It is characterized by calculating each item belonging to the eternal element at a time, rather than storing them all in memory, as is done without the generator. This feature is known for 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) {
  let 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 gigantesto value, such as a million elements, it would probably affect the yield of its application.

With the use of the generator:

function* fibonacci(n) {
  let 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);
}

The elements of the list will not be in memory when we do const sequence = fibonacci(10), they shall be calculated within the for, only when used, by 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 in your application (running time would remain high, as it would continue to run millions of operations, but in memory, would not be affected).

Iterator

The return of a generator is a iterator and therefore implements the next.

Tabela que descreve o método next.

Utilizing

Imagine that you want to display a list of all the names of the cities of Brazil, which total a number of approximately 5570, using Infinite scroll. Storing in memory the data from these 5570 records would be unnecessary, as the user will hardly use all of them. Then you could display on screen an initial amount, 20 for example, and when the user requires more, when reaching the end of the list, make, with the generator, an AJAX request to the server requesting 10 more records and adding them to the list. This way, the 5570 records would only be in memory if the user requested it.

Related

The Fibonacci sequence, although not widely used in practice, was used as an example due to ease of implementation.

  • Interesting! So for operations of this type it is convenient to use the mechanics of yield same? Since it has much less impact on memory usage..

  • Damn that answer. + 1

  • Thank you very much! If I could give +2 I would, because of the idea of using in Infinite scroll, which is a very common practice in my projects!

  • @Arturtrapp, I added the comment to the reply.

  • Is there any way to turn a generator into an array directly?

  • @Miguel, I believe with the Array.from, but I’m not sure.

  • @Andersoncarloswoss, no problem when I get home I see it. Good answer

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.