function* fetchUsers(ids) {
for (const id of ids) {
yield fetch(`/api/users/${id}`).then(r => r.json());
// ^^^ yields a Promise, not the resolved value
}
}
async function getAll(ids) {
const users = [];
for (const result of fetchUsers(ids)) {
users.push(result); // result is a Promise, not a user!
}
return users; // array of Promises ❌
}// Fix 1: async generator (use for await...of)
async function* fetchUsers(ids) {
for (const id of ids) {
const user = await fetch(`/api/users/${id}`).then(r => r.json());
yield user; // yield resolved value
}
}
async function getAll(ids) {
const users = [];
for await (const user of fetchUsers(ids)) {
users.push(user); // ✅ actual user objects
}
return users;
}
// Fix 2: parallel (faster)
async function getAllParallel(ids) {
return Promise.all(ids.map(id =>
fetch(`/api/users/${id}`).then(r => r.json())
));
}Bug: Regular generators can't await — yield hands back whatever you give it, including unresolved Promises. The consumer receives Promises, not user data.
Explanation: Regular generators are synchronous. To yield resolved async values, you need an async generator (async function*), consumed with for await...of.
Key Insight: Regular generator + async work = yields Promises. Async generator = yields resolved values. Always use async function* with for await...of for async iteration.