JS — Generator Functions vs Async/Await
YouTube: https://www.youtube.com/@RoadToCodeWithMB/playlists
A generator function in JavaScript is a special kind of function that can pause execution and later resume from where it left off.
They are defined with an * (asterisk) and use the yield keyword.
Basic Syntax
function* myGenerator() {
yield 1;
yield 2;
yield 3;
}🔹 How it works
const gen = myGenerator();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }
console.log(gen.next()); // { value: undefined, done: true }gen.next()executes the generator until the nextyield.- Each call returns an object
{ value, done }. - When finished,
done: true.
🔹 Why use Generators?
- Lazy evaluation → Generate values one by one, instead of building a huge array in memory.
- Infinite sequences → Useful when you don’t know how many items you need.
- Async-like flows (before
async/await, generators were used with promises).
🔹 Example 1: Infinite Counter
function* counter() {
let i = 1;
while (true) {
yield i++;
}
}
const gen = counter();
console.log(gen.next().value); // 1
console.log(gen.next().value); // 2
console.log(gen.next().value); // 3🔹 Example 2: Iterating over custom logic
function* evenNumbers(limit) {
for (let i = 0; i <= limit; i++) {
if (i % 2 === 0) yield i;
}
}
for (let num of evenNumbers(10)) {
console.log(num); // 0, 2, 4, 6, 8, 10
}🔹 Example 3: Async-like flow
function* fetchData() {
console.log("Start fetching...");
yield "Step 1: Request sent";
yield "Step 2: Processing";
return "Step 3: Done";
}
const gen = fetchData();
console.log(gen.next().value); // Start fetching... + Step 1
console.log(gen.next().value); // Step 2
console.log(gen.next().value); // Step 3
/*
Output
Start fetching...
Step 1: Request sent
Step 2: Processing
Step 3: Done*/
✅ In short:
Generator functions are like iterators you can pause and resume, using yield. They’re powerful for building custom iterators, infinite sequences, lazy evaluation, and controlling execution flow.
Question: Compare Generators vs Async/Await, since both can “pause” execution but in different ways
Get Manohar Batra’s stories in your inbox
Join Medium for free to get updates from this writer.
Both generators and async/await can pause execution, but they solve different problems.
🔹 Generators vs Async/Await
1. Generators (function*)
- Pause execution at
yield. - Resume manually using
.next(). - Return an iterator object.
- Useful for custom iteration, lazy evaluation, infinite sequences.
Example
👉 Here, you manually control execution
function* counter() {
yield 1;
yield 2;
yield 3;
}
const gen = counter();
console.log(gen.next()); // { value: 1, done: false }
console.log(gen.next()); // { value: 2, done: false }
console.log(gen.next()); // { value: 3, done: false }2. Async/Await
- Built on Promises.
- Pause execution at
await. - Resume automatically when the Promise resolves.
- Useful for asynchronous workflows (e.g., API calls).
Example
async function fetchData() {
console.log("Fetching...");
const data = await fetch("https://jsonplaceholder.typicode.com/todos/1")
.then(res => res.json());
console.log(data);
}
fetchData();👉 Here, execution pauses at await until the promise resolves, then continues automatically.
🔹 Bridge Between Them
Before async/await existed, libraries like co used generators + promises to mimic async/await.
Example:
function* task() {
const res = yield fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = yield res.json();
console.log(data);
}👉 With a runner, this looks like async/await, but today we just write:
async function task() {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await res.json();
console.log(data);
}✅ In short:
- Use generators when you want custom iteration or lazy evaluation.
- Use async/await when you want simpler async code with promises.




