1. Callbacks: Passing Functions as Instructions JavaScript
const announceHit = (target) => {
console.log(`${target} took 25 damage!`);
};
const swingSword = (target, callback) => {
console.log(`Swinging at ${target}...`);
callback(target);
};
swingSword("Goblin", announceHit);
2. Error-First Callbacks and the Node Convention JavaScript
function openLootChest(chestId, callback) {
setTimeout(() => {
const loot = "Dragon Slayer Sword";
callback(null, loot);
}, 100);
}
openLootChest("chest_42", (err, item) => {
if (err) {
console.log("Loot failed:", err.message);
return;
}
console.log("You found:", item);
});
console.log("Opening the chest...");
3. Callback Hell: When Nesting Goes Wrong JavaScript
function findHero(cb) {
setTimeout(() => {
cb(null, "Aerith");
}, 40);
}
function pickWeapon(hero, cb) {
setTimeout(() => {
cb(null, "Princess Guard");
}, 40);
}
findHero((err, hero) => {
pickWeapon(hero, (err, weapon) => {
console.log(hero + " readies " + weapon);
});
});
4. Timers and Scheduling: setTimeout, setInterval, and Zero Delay JavaScript
console.log("Hero begins channeling Fireball");
setTimeout(() => {
console.log("BOOM! 80 damage dealt!");
}, 1500);
console.log("Hero dodges while channeling");
5. Event Emitters: The Publish-Subscribe Pattern JavaScript
const { EventEmitter } = require('node:events');
const guild = new EventEmitter();
guild.on('questComplete', () => {
console.log('Quest done! 100 XP earned!');
});
guild.emit('questComplete');
6. Creating and Consuming Promises JavaScript
const plate = new Promise((resolve, reject) => {
resolve("Souffle is ready!");
});
plate.then((dish) => {
console.log("Service:");
console.log(dish);
});
console.log("Order fired...");
7. Chaining: Flattening the Pyramid JavaScript
const lootChest = Promise.resolve(100);
lootChest
.then(gold => {
console.log(`Found ${gold} gold!`);
return gold * 2;
})
.then(doubled => {
console.log(`Doubled to ${doubled}!`);
return doubled + 50;
})
.then(final => {
console.log(`Bonus! Total: ${final}.`);
});
8. Error Propagation and finally JavaScript
const openCase = () =>
Promise.resolve("Case file opened.");
const verifyLead = (msg) => {
console.log(msg);
throw new Error("Missing witness statement!");
};
const closeCase = () => {
console.log("Case closed!");
};
openCase()
.then(verifyLead)
.then(closeCase)
.catch(err => {
console.log("Setback:", err.message);
});
9. Running in Parallel: Promise.all and Promise.allSettled JavaScript
const openChest = (name, ms, loot) =>
new Promise((resolve) => {
setTimeout(() => resolve(loot), ms);
});
async function main() {
const drops = await Promise.all([
openChest("Gold", 200, "120 Gold"),
openChest("Gem", 300, "Ruby Shard"),
openChest("Rune", 250, "Frost Rune"),
]);
console.log("Loot acquired:");
for (const item of drops) {
console.log(" " + item);
}
}
main();
10. Racing Promises: Promise.race and Promise.any JavaScript
const filing = (name, ms) =>
new Promise((resolve) =>
setTimeout(() => resolve(name), ms)
);
async function main() {
const winner = await Promise.race([
filing("Reuters", 300),
filing("AP", 200),
filing("Bloomberg", 500),
]);
console.log(`First to file: ${winner}!`);
}
main();
11. async and await: Synchronous-Looking Async Code JavaScript
const delay = (ms) =>
new Promise(r => setTimeout(r, ms));
function loadUser() {
return delay(80).then(() => ({
name: 'Ada', hp: 100
}));
}
function addRole(user) {
return delay(60).then(() => ({
...user, role: 'admin'
}));
}
loadUser()
.then(user => addRole(user))
.then(ready => {
console.log(ready.name + ' is ready!');
console.log('Role: ' + ready.role);
});
12. Error Handling with try/catch/finally JavaScript
async function castSpell(spell) {
if (spell === "fizzle") {
throw new Error("Spell fizzled!");
}
return `${spell} hits for 42 damage!`;
}
async function main() {
try {
const result = await castSpell("fizzle");
console.log(result);
} catch (err) {
console.log("Caught:", err.message);
}
}
main();
13. Sequential vs Parallel await: A Common Performance Trap JavaScript
const fetchParcel = async (name, ms) => {
await new Promise(r => setTimeout(r, ms));
return `${name} delivered!`;
};
async function main() {
const start = Date.now();
const boston = await fetchParcel("Boston", 800);
const denver = await fetchParcel("Denver", 800);
const austin = await fetchParcel("Austin", 800);
const total = Date.now() - start;
console.log(boston);
console.log(denver);
console.log(austin);
console.log(`Took ${total} ms total!`);
}
main();
14. Awaiting in Loops: forEach Traps and for-of Fixes JavaScript
const section = ["Violins", "Cellos", "Flutes"];
const tuneUp = async (name) => {
await new Promise(r =>
setTimeout(r, 100));
console.log(`${name} tuned!`);
};
const main = async () => {
section.forEach(async (name) => {
await tuneUp(name);
});
console.log("Orchestra ready!");
};
main();
15. Cancellation with AbortController JavaScript
// Spawn a controller for our quest
const ctrl = new AbortController();
const sig = ctrl.signal;
// Live and ready, no abort yet
console.log("Quest open!");
console.log("Aborted?", sig.aborted);
// Hero pulls the rip cord
ctrl.abort();
console.log("Hero fled the battle!");
console.log("Aborted?", sig.aborted);
16. Macrotasks vs Microtasks: The Two Queues JavaScript
console.log('Power up requested');
Promise.resolve('mana boost').then(value => {
console.log('Got:', value);
});
console.log('Battle continues');
17. queueMicrotask and Manual Scheduling JavaScript
console.log("Quest started");
queueMicrotask(() => {
console.log("Loot picked up");
});
console.log("Quest ending");
18. Ordering Puzzles: Predicting the Output JavaScript
console.log("Hero enters dungeon");
setTimeout(() => {
console.log("Trap triggers!");
}, 0);
Promise.resolve().then(() => {
console.log("Shield blocks!");
});
console.log("Hero swings sword");
19. Starving the Loop: When Microtasks Attack JavaScript
// Boss attack scheduled in 50ms
setTimeout(() => {
console.log("Boss strikes for 200 damage!");
}, 50);
let casts = 0;
const echoSpell = () => {
casts = casts + 1;
if (casts < 100000) {
queueMicrotask(echoSpell);
} else {
console.log("Echo spell finished");
}
};
queueMicrotask(echoSpell);
console.log("Player casts Echo!");
20. Offloading Heavy Work to Worker Threads JavaScript
function grindPrimes(limit) {
let count = 0;
for (let n = 2; n < limit; n++) {
let prime = true;
for (let d = 2; d * d <= n; d++) {
if (n % d === 0) { prime = false; break; }
}
if (prime) count++;
}
return count;
}
const tick = setInterval(() => {
console.log("Boss timer tick!");
}, 100);
console.log("Grinding primes...");
const total = grindPrimes(8_000_000);
console.log(`Found ${total} primes.`);
clearInterval(tick);
21. Async Generators and for-await-of JavaScript
const sleep = (ms) =>
new Promise((r) => setTimeout(r, ms));
async function* lootStream() {
yield "Iron Sword";
await sleep(50);
yield "Health Potion";
await sleep(50);
yield "Dragon Scale";
}
async function main() {
const drops = lootStream();
const first = await drops.next();
console.log("Drop:", first.value);
const second = await drops.next();
console.log("Drop:", second.value);
}
main();
22. Building an Async Iterator by Hand JavaScript
const wait = ms =>
new Promise(r => setTimeout(r, ms));
const dropper = {
drops: ["Iron Sword", "Mana Potion"],
i: 0,
async next() {
await wait(200);
if (this.i >= this.drops.length) {
return { value: undefined, done: true };
}
const v = this.drops[this.i++];
return { value: v, done: false };
}
};
async function main() {
console.log(await dropper.next());
console.log(await dropper.next());
console.log(await dropper.next());
}
main();
23. Streaming Data and Backpressure JavaScript
async function* lootStream() {
const drops = ["Sword", "Shield", "Gem"];
for (const drop of drops) {
await new Promise(
(r) => setTimeout(r, 100)
);
yield drop;
}
}
async function main() {
for await (const item of lootStream()) {
console.log(`Got: ${item}!`);
}
}
main();
24. Combining Async Streams and Early Exit JavaScript
const sleep = (ms) =>
new Promise((r) => setTimeout(r, ms));
async function* dungeonLoot(name, items) {
for (const item of items) {
await sleep(80);
yield `${name}: ${item}`;
}
}
async function main() {
const cave = dungeonLoot(
"Crystal Cave",
["Ruby", "Emerald", "Sapphire"]
);
for await (const drop of cave) {
console.log(drop);
}
}
main();
25. A Practical Async Pipeline End to End JavaScript
async function* fetchDungeons() {
const pages = [
["Wraith", "Imp"],
["Ogre", "Lich"]
];
for (const p of pages) {
await new Promise(r =>
setTimeout(r, 40));
yield p;
}
}
async function main() {
for await (const page of fetchDungeons()) {
console.log("Page:", page);
}
}
main();