DEV Community

sujithakumar
sujithakumar

Posted on

Discover the Power of JavaScript Generators: Pause, Play, and Supercharge Your Code! ๐Ÿš€

Ready to discover a secret weapon in JavaScript? ๐Ÿš€ Today, weโ€™re diving into Generators, those incredible functions that can pause and resume their execution on demand. Cool, right? Letโ€™s unpack this magic with real-world examples to level up your coding game!

What are Generators?
In simple terms, a Generator is a special function in JavaScript. Unlike regular functions that run from start to finish, generators can yield values at different points and pick up right where they left off.

Generators use the function* syntax **(note the asterisk) and the **yield keyword to pause execution. When you invoke a generator function, it doesnโ€™t immediately execute like a regular function. Instead, it returns a special object called an iterator, which is capable of pausing and resuming execution.

Letโ€™s start with a simple example to see how generators work:

function* myGenerator() {
  yield 1;
  yield 2;
  yield 3;
  return "Done!";
}
const gen = myGenerator();
console.log(gen); 
// Output : Object [Generator] {}
Enter fullscreen mode Exit fullscreen mode

When you call a generator function, it doesnโ€™t execute its code immediately. Instead, it returns a special Generator object- an iterator that follows the Iterator Protocol.

console.log(gen.next()); // Output : { value: 1, done: false }
  console.log(gen.next()); // Output : { value: 2, done: false }
  console.log(gen.next()); // Output : { value: 3, done: false }
  console.log(gen.next()); // Output : { value: "Done!", done: true }
Enter fullscreen mode Exit fullscreen mode

Each call to its next() **method runs the generator until the next yield, returning a { value, done } pair. When the generator has no more values to yield, **it returns { done: true }.

When to Use Generators?
โ€ข Lazy Evaluation: Fetch or process data only when needed.
โ€ข State Machines: Handle complex state transitions.
โ€ข Iterative Tasks: Paginate, process streams, or generate sequences dynamically.

Async Generators:
We'll create an async generator that simulates fetching paginated data from an API. For simplicity, weโ€™ll return hardcoded "pages" of data.

async function* fetchUserPages() {
  let page = 1;
  while (page <= 3) {  
    console.log(`Fetching page ${page}...`);

    // Simulating an API request that returns users for the current page
    const users = await new Promise(resolve => {
      setTimeout(() => {
        resolve([`User ${page * 1}`, `User ${page * 2}`, `User ${page * 3}`]);
      }, 1000); // Simulating 1 second delay for each page
    });
yield users;  // Yield the users from the current page
    page++; 
  }
}
Enter fullscreen mode Exit fullscreen mode

The await new Promise() part simulates an asynchronous API request that returns an array of users after a delay (1 second).
Each time we yield users, the generator pauses and sends the data.

 (async () => {
    const userGenerator = fetchUserPages();  

    for await (const users of userGenerator) {
      console.log("Received Users:", users); 
    }

    console.log("All pages fetched!");
  })();
Enter fullscreen mode Exit fullscreen mode

Output (in the console):

Fetching page 1...
Received Users: [ 'User 1', 'User 2', 'User 3' ]
Fetching page 2...
Received Users: [ 'User 2', 'User 4', 'User 6' ]
Fetching page 3...
Received Users: [ 'User 3', 'User 6', 'User 9' ]
All pages fetched!
Enter fullscreen mode Exit fullscreen mode

Key Takeaways:
Async generators with the for await...of loop offer a clean and efficient way to handle asynchronous operations. The await inside the generator ensures non-blocking execution, so other tasks can continue while waiting for data. The yield keyword allows us to return data in chunks (pages), keeping memory usage low. The for await...of loop simplifies consuming the generator, automatically managing asynchronous behavior, making the code more readable and intuitive.

Final Thoughts ๐ŸŽ‰
Async generators may seem tricky at first, but with some practice, theyโ€™ll quickly become a powerful tool in your JavaScript skillset. Start by experimenting with the basics, and soon you'll be handling asynchronous workflows like a pro! ๐Ÿ’ช
_Want to share how youโ€™ve used async generators? Drop a comment belowโ€”letโ€™s learn together! ๐Ÿ™Œ

Happy coding! ๐Ÿ’ป_

Top comments (0)