JavaScript Medium technical 1 views 2 min read

What is the difference between synchronous and asynchronous generators?

Peer-reviewed by HireXTech Technical Panel Updated for 2025/2026 hiring Editorial standards
Practise this track
Interviewer Expectations for this Question
01
Core Competency

Assesses fundamental understanding of JavaScript conventions, runtime behavior, and memory/performance considerations.

02
Evaluation Criteria

Hiring managers look for precision, avoidance of ambiguous jargon, and ability to explain trade-offs under real production conditions.

Comprehensive Model Answer Verified Solution

Synchronous and asynchronous generators differ in how they produce values and handle asynchronous operations.

Synchronous generator:

     function* syncGenerator() {
       yield 1;
       yield 2;
       yield 3;
     }

     const gen = syncGenerator();
     console.log(gen.next()); // { value: 1, done: false }
     console.log(gen.next()); // { value: 2, done: false }
     

Asynchronous generator:

     async function* asyncGenerator() {
       yield await Promise.resolve(1);
       yield await Promise.resolve(2);
       yield await Promise.resolve(3);
     }

     (async () => {
       for await (const value of asyncGenerator()) {
         console.log(value); // 1, 2, 3
       }
     })();
     

Comparison:

| Synchronous Generator | Asynchronous Generator |
|----------------------|------------------------|
| function* | async function* |
| Returns iterator | Returns async iterator |
| .next() returns { value, done } | .next() returns Promise<{ value, done }> |
| Used with for...of | Used with for await...of |
| Cannot await inside | Can await inside |

Practical example - data streaming:

     // Sync generator - in-memory data
     function* readFileSync(lines) {
       for (const line of lines) {
         yield line;
       }
     }

     // Async generator - streaming data
     async function* readFileAsync(filePath) {
       const stream = createReadStream(filePath);
       const reader = stream.getReader();

       while (true) {
         const { done, value } = await reader.read();
         if (done) break;
         yield value;
       }
     }
     

Async generator with delays:

     async function* ticker(interval, max) {
       let count = 0;
       while (count < max) {
         await new Promise(resolve => setTimeout(resolve, interval));
         yield count++;
       }
     }

     (async () => {
       for await (const tick of ticker(1000, 5)) {
         console.log(tick); // 0, 1, 2, 3, 4 (one per second)
       }
     })();
     

Combining generators:

     async function* fetchPages(urls) {
       for (const url of urls) {
         const response = await fetch(url);
         yield await response.json();
       }
     }

     async function* processPages(urls) {
       for await (const page of fetchPages(urls)) {
         yield processPage(page);
       }
     }
     

Candidate Response Strategy & Interview Tips

  1. Start with a concise one-sentence summary: Deliver a direct, confident answer first before expanding into nuances.
  2. Demonstrate real-world trade-offs: Discuss where this approach excels and when you would avoid it in production systems.
  3. Discuss complexity & edge cases: Proactively explain time/space complexity or boundary conditions (null values, scale limits).
  4. Prepare for interviewer follow-ups: Technical hiring panels frequently probe deeper into concurrency, backward compatibility, or alternative libraries.
Related Topics & Skills
Spotted an error or have an alternative solution?