Advanced JavaScript flashcards: event loop, generators and more
Fifty advanced JavaScript cards: event-loop ordering puzzles, generators and async iteration, this binding, Proxy and Reflect, modules, AbortController and coercion edge cases.
Practice now
Study without an account
console.log(1)
setTimeout(() => console.log(2))
queueMicrotask(() => console.log(3))
Promise.resolve().then(() => console.log(4))
console.log(5)Scheduled with the default Askesis timings. Progress is saved in this browser.
All 50 cards
- 1In what order does this log?js
console.log(1) setTimeout(() => console.log(2)) queueMicrotask(() => console.log(3)) Promise.resolve().then(() => console.log(4)) console.log(5)1 5 3 4 2: synchronous code, then microtasks in the order they were queued, then the timer - 2In what order does this log?js
async function f() { console.log('a') await null console.log('b') } f() console.log('c')a c b: everything afterawaitruns later as a microtask - 3In what order does this log?js
Promise.resolve().then(() => { console.log('m1') setTimeout(() => console.log('t2')) }) setTimeout(() => { console.log('t1') Promise.resolve().then(() => console.log('m2')) })m1 t1 m2 t2: after each task (like a timer callback) the microtask queue is drained before the next task - 4Can microtasks starve the page?Yes. Microtasks queued by microtasks all run before rendering or the next timer, so an endless chain freezes the page
- 5When does a
requestAnimationFramecallback run?Before the browser’s next repaint, usually about 60 times a second; it’s paused in background tabs - 6What does
Promise.withResolvers()return?{ promise, resolve, reject }, so you can settle a promise from outside its executor (ES2024) - 7What happens to a rejected promise nobody handles?Browsers fire an
unhandledrejectionevent; Node.js crashes the process by default (since Node 15) - 8Sequential vs concurrent awaitsjs
// one after another for (const url of urls) await fetch(url) // all at once await Promise.all(urls.map((url) => fetch(url))) - 9Why write
return awaitinsidetry?Withoutawait, a rejection happens after the function returns, so the surroundingcatchnever sees itjstry { return await risky() } catch (err) { return fallback } - 10What does
for await...ofiterate?Async iterables (and sync iterables of promises), awaiting each value in turn - 11What is an async generator?An
async function*that canawaitandyield; consume it withfor awaitjsasync function* pages(url) { while (url) { const res = await (await fetch(url)).json() yield res.items url = res.next } } - 12What does calling a generator function return?An iterator; the body runs only when you call
next(), pausing at eachyieldjsfunction* ids() { let i = 0 while (true) yield i++ } const it = ids() it.next().value // 0 - 13What does an iterator’s
next()return?{ value, done };doneistrueonce the iterator is exhausted - 14Make an object iterableGive it a
[Symbol.iterator]method that returns an iterator (a generator is easiest)jsconst range = { from: 1, to: 3, *[Symbol.iterator]() { for (let i = this.from; i <= this.to; i++) yield i }, } [...range] // [1, 2, 3] - 15What does
Symbol.asyncIteratorenable?Using an object withfor await...of - 16What does
Symbol.toPrimitivecustomize?How an object converts to a primitive; it receives a hint:"number","string"or"default" - 17What does
Object.create(null)give you?An object with no prototype: no inherited keys liketoString, handy as a plain dictionary - 18Class method vs arrow-function class fieldMethods live once on the prototype; arrow fields are created per instance and keep
thisboundjsclass Button { click() {} // shared, on the prototype onClick = () => {} // per instance, `this` fixed } - 19Where do
staticclass members live?On the class (constructor) itself, not on instances - 20In a subclass constructor, what must happen before you use
this?A call tosuper(...); usingthisfirst throws a ReferenceError - 21Precedence of the
thisbinding rulesnew› explicit (call/apply/bind) › method call (obj.fn()) › default (undefinedin strict mode) - 22Why is
thisundefined here?const f = obj.method; f()The method was called without its object; bind it (obj.method.bind(obj)) or wrap it in an arrowIn strict mode (modules, classes) it’sundefined; in sloppy scripts it’s the global object. - 23Can you change
thisby callingbindon a bound function?No. The firstbindwins; laterbindcalls can only add arguments - 24Break out of a nested loopLabel the outer loop and
breakto the labeljsouter: for (const row of grid) { for (const cell of row) { if (cell === target) break outer } } - 25What does this log?js
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i)) }3 3 3: one sharedvar. Withlet, each iteration gets its own binding and it logs0 1 2 - 26How do closures cause memory leaks?A closure keeps everything it captures alive while the function is reachable, so long-lived listeners and timers can pin large objects
- 27What does
WeakRefdo?Holds an object without keeping it alive;ref.deref()returns it, orundefinedonce it’s collected - 28What is
FinalizationRegistryfor?Running a callback some time after a registered object is garbage-collected; timing isn’t guaranteed - 29A typical use of
WeakSetMarking objects (like “already processed”) without stopping them from being garbage-collected - 30What is a
Proxy?A wrapper that intercepts operations on an object through traps likeget,setandhasjsconst logged = new Proxy(target, { get(t, key, receiver) { console.log('read', key) return Reflect.get(t, key, receiver) }, }) - 31Why use
Reflectinside proxy traps?Reflect.get,Reflect.setand friends perform the default operation, so a trap can add behavior and then forward - 32Define a getter and a setterjs
const user = { first: 'Ada', last: 'Lovelace', get full() { return `${this.first} ${this.last}` }, set full(v) { [this.first, this.last] = v.split(' ') }, } - 33Defaults of
writable,enumerableandconfigurablewithObject.definePropertyAllfalseunless you set them - 34Is
Object.freezedeep?No, it’s shallow: nested objects stay mutable. Writes to a frozen property fail silently, or throw in strict mode - 35What can’t
structuredClonecopy?Functions and DOM nodes (it throws), and it drops prototypes, so class instances come back as plain objects - 36ES modules vs CommonJSESM
import/exportis static, loaded asynchronously and always strict; CommonJSrequireruns synchronously at call time - 37What is a live binding?An ES module import that reflects later changes to the exported variable; CommonJS copies the value when you
requireit - 38Load a module on demandjs
const { render } = await import('./chart.js')Dynamicimport()returns a promise and enables code splitting. - 39Where is top-level
awaitallowed?In ES modules. Modules that import one wait for it to finish evaluating - 40ThrottleRun a function at most once per intervaljs
function throttle(fn, ms) { let last = 0 return (...args) => { const now = Date.now() if (now - last >= ms) { last = now fn(...args) } } } - 41Cancel a
fetchjsconst ctrl = new AbortController() fetch(url, { signal: ctrl.signal }) ctrl.abort() // the fetch rejects with an AbortError - 42Give a
fetcha timeoutjsfetch(url, { signal: AbortSignal.timeout(5000) })It rejects with a TimeoutError after 5 seconds. - 43
Uint8ArrayvsUint8ClampedArrayBoth store bytes; out-of-range values wrap around inUint8Array(256 → 0) and clamp to 0–255 in the clamped one - 44What does a template tag function receive?The literal string parts, then the interpolated valuesjs
function upper(strings, ...values) { return strings.reduce((out, s, i) => out + s + (values[i]?.toUpperCase() ?? ''), '') } upper`hi ${'ada'}!` // 'hi ADA!' - 45
Object.is(-0, 0)andObject.is(NaN, NaN)falseandtrue, the opposite of=== - 46
[] + {}and[] + []'[object Object]'and'': both sides convert to strings, then concatenate - 47
'5' - 2vs'5' + 23vs'52':-converts to numbers,+concatenates when either side is a string - 48
0.1 + 0.2 === 0.3false; floating-point rounding gives0.30000000000000004Compare with a tolerance:Math.abs(a - b) < Number.EPSILON. - 49Group array items by a keyjs
Object.groupBy(cards, (c) => c.deck) // { Japanese: [...], Spanish: [...] }ES2024.Map.groupBydoes the same into a Map. - 50
sortvstoSortedsortreorders the array in place;toSortedreturns a sorted copy (ES2023)
Frequently asked questions
Should I start with this deck?
Start with JavaScript essentials. This deck assumes you know closures, promises and array methods.
Are the event-loop answers the same in Node.js?
Yes for these examples: microtasks run before the next timer callback in both browsers and Node.js.
Is it useful for senior interviews?
Yes. Event-loop ordering, this binding and generators are classic senior-level questions.
More in Programming
JavaScript
Master the JavaScript every developer uses daily: scope, closures, equality, array methods, promises, async/await and the event loop.
50 cardsTypeScript
Learn the TypeScript you use every day: narrowing, generics, keyof, mapped and conditional types, utility types, satisfies and strict mode, with code on every card.
50 cardsPython
Learn idiomatic Python fast: comprehensions, f-strings, args and kwargs, generators, decorators, context managers and the standard library.
50 cardsGit & terminal
The Git commands and shell skills developers use every day: branching, rebasing, undoing mistakes, pipes, redirects, permissions and processes.
50 cardsJava
Core Java with short snippets: equals vs ==, records, sealed types, collections, generics, exceptions, streams, lambdas and JVM basics.
50 cardsC#
C# and .NET fundamentals with short snippets: value vs reference types, properties, records, nullable reference types, LINQ, async/await and DI.
50 cardsKotlin
Kotlin fundamentals with short snippets: null safety, val vs var, data and sealed classes, extension functions, scope functions and coroutines.
50 cardsSwift
Swift fundamentals with short snippets: optionals, structs vs classes, protocols, enums with associated values, closures, ARC, async/await and SwiftUI.
50 cardsFlutter
Flutter and Dart basics: null safety, futures and streams, stateless vs stateful widgets, setState, hot reload, keys, layout and state management.
50 cardsPHP
Modern PHP 8 with short snippets: strict types, arrays, match, nullsafe and named arguments, enums, readonly, Composer, PDO and password_hash.
50 cardsRuby
Ruby fundamentals with short snippets: blocks, procs and lambdas, symbols, Enumerable, mixins, truthiness, method_missing, gems and Bundler.
50 cardsGo
Go (Golang) fundamentals with short, idiomatic snippets: slices vs arrays, maps, defer, error wrapping, interfaces, goroutines, channels, select and context.
50 cardsRust
Learn the Rust that the compiler keeps asking about: ownership, borrowing, lifetimes, Option and Result, traits, closures, smart pointers and async.
50 cardsC++
Modern C++ in short snippets: references vs pointers, RAII, smart pointers, move semantics, STL containers and algorithms, const, templates and UB.
50 cardsHaskell
Haskell fundamentals with short code: types and type classes, pattern matching, laziness, Maybe and Either, folds, Functor, Applicative and Monad.
50 cardsElixir
Elixir fundamentals with short snippets: immutability, pattern matching, the pipe operator, Enum vs Stream, processes, GenServer, supervisors and mix.
50 cardsx86-64 assembly
x86-64 assembly in Intel syntax: registers and sub-registers, flags, mov and lea, jumps, the stack frame, the System V calling convention and Linux syscalls.
50 cardsRegex
Learn regular expressions for good: anchors, classes, greedy vs lazy quantifiers, groups, lookarounds, flags, replacements and the backtracking trap.
50 cards