Unlocking the Power of JavaScript Generators 🦾⏭️
Tags: webdev, javascript, beginners, tutorial
Published: 2023-10-03 04:00:00

### Hello coders! 🧙‍♂️

Have you ever heard of **Generator Functions** in JavaScript?
These were introduced in 2015, with the **ES6** update and they allow you to create iterators in a more convenient and expressive way.

Generator functions have a pretty *weird syntax*. You can declare a generator function with the `function` keyword followed by an asterisk (`*`). 🤔

```js
function* myGenerator() {
  // generator code here
}
```

Note that unlike normal functions, *you can't declare a generator function with arrow syntax*. ⚠️

Inside a generator function, you can use the `yield` statement to produce a value that can be iterated over.
The generator function's execution can be paused and resumed as needed. This makes it suitable for dealing with asynchronous operations, such as fetching data from a server.

We can call the `next()` method on the generator to run the execution until the nearest `yield` statement.

```js
function* myGenerator() {
  yield 1;
  yield 2;
  return 3;
}

const generator = myGenerator();
console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: true }
```

As we can see, the `next()` method returns a object with two properties: `value` (the value yielded in the function) and `done` (`true` if the function returned a value with `return` instead of `yield`, since it's now finished). ⏭️

```ts
// In TypeScript 🟦
interface NextReturns {
  value: any; // or unknown, for TypeScript lovers ;D
  done: boolean;
}
```

Let's now see some real world examples for this strange feature! 😊
We could start by creating a function that **generates** and infinite sequence of numbers (useful when you need to assign IDs to objects or classes for example):

```js
function* infiniteNumbers() {
  let num = 1;
  while (true) {
    yield num++;
  }
}

const numGenerator = infiniteNumbers();
console.log(numGenerator.next().value); // 1
console.log(numGenerator.next().value); // 2
console.log(numGenerator.next().value); // 3
// You can keep calling numGenerator.next() to get the next number. ♾️
```

Generator functions can produce sequences with conditions too. For example, you can create a generator that yields a sequence of numbers from a start to a certain limit.

```js
function* generateSequence(start, end) {
  for (let i = start; i <= end; i++) yield i;
}

const sequenceGenerator = generateSequence(1, 5);

for (const value of sequenceGenerator) {
  console.log(value);
}
/* 1
   2
   3
   4
   5 
*/
```

We could use generators to create a function that automatically implements pagination with asynchronous data fetching:

```js
async function* paginateData() {
  let page = 1;
  while (true) {
    const data = await fetchData(page);
    if (data.length === 0) break;
    yield data;
    page++;
  }
}

const dataPaginator = paginateData();

(async () => {
  for await (const chunk of dataPaginator) {
    // Process and display the data chunk
    console.log(chunk);
  }
})();
```

There are a lot of other cases in which generators can be useful, but from now I'll leave playing with it to you, hoping you loved this weird feature as much as I did when I learnt it for the first time 😍.

Some nice resource I found if you want to dive deeper:

- [javascript.info](https://javascript.info/generators)
- [MDN web docs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/GeneratorFunction)
- [Web Dev Simplified](https://www.youtube.com/watch?v=IJ6EgdiI_wU)

### Who am I? 

I am an Italian high-school student who is interested in web-dev 🧙‍♂️. If you'd like to support me, you can follow me here and on my [GitHub](https://github.com/alessandrofoglia07), I would really appreciate it 💜