Promise.withResolvers & Deferreds
intermediateThe ES2024 way to create a promise you settle from outside — and how to implement the deferred pattern it replaces.
The ES2024 and ES2025 features interviewers now expect — Object.groupBy, Promise.withResolvers, Set methods, iterator helpers, RegExp v flag, and more.
Senior interviews increasingly end implementation questions with a twist: "Nice — does the language give you this for free now?" Knowing that Object.groupBy replaces a hand-rolled reduce, or that Promise.withResolvers replaces the deferred pattern, signals that you keep current. This page is the shortlist that actually comes up.
Grouping — previously the most-written reduce in existence — is now built in:
const orders = [
{ id: 1, status: "paid" },
{ id: 2, status: "pending" },
{ id: 3, status: "paid" },
];
const byStatus = Object.groupBy(orders, (o) => o.status);
// { paid: [{id:1},{id:3}], pending: [{id:2}] }
const map = Map.groupBy(orders, (o) => o.status); // Map for arbitrary keysInterview notes: the result of Object.groupBy has a null prototype (no inherited keys — see prototypal inheritance), and Map.groupBy is the right choice when group keys are objects.
Creates a promise plus its resolve/reject functions in one call — the standardized "deferred" pattern. It has its own deep dive in this catalog.
const { promise, resolve, reject } = Promise.withResolvers();A stricter, more powerful Unicode mode enabling set operations in character classes:
/[\p{Script=Latin}&&\p{Uppercase}]/v.test("A"); // intersection: uppercase LatinYou won't be asked to write these, but recognizing && (intersection) and -- (difference) inside [...] shows currency.
String.prototype.isWellFormed() and toWellFormed() detect/repair lone surrogates — relevant when an interviewer probes string edge cases (pairs nicely with custom trim follow-ups).
Await a change to shared memory without blocking the thread — niche, but name-droppable when worker communication comes up.
map, filter, take, drop, flatMap, reduce, toArray, forEach, some, every, and find directly on iterators — lazily evaluated. Big enough to get its own page.
function* naturals() { let n = 1; while (true) yield n++; }
const firstFiveEvenSquares = naturals()
.filter((n) => n % 2 === 0)
.map((n) => n * n)
.take(5)
.toArray(); // [4, 16, 36, 64, 100] — no infinite array materializedReal set algebra, finally:
const a = new Set([1, 2, 3]);
const b = new Set([2, 3, 4]);
a.intersection(b); // Set {2, 3}
a.union(b); // Set {1, 2, 3, 4}
a.difference(b); // Set {1}
a.symmetricDifference(b); // Set {1, 4}
a.isSubsetOf(b); // false
a.isDisjointFrom(new Set([9])); // trueIf an interviewer asks you to dedupe-and-compare arrays, converting to Set and using these beats nested loops — and stating the O(n) vs O(n·m) difference earns the point.
Safely embed user input in a dynamic regex — the standard answer to a long-standing footgun:
const re = new RegExp(RegExp.escape(userInput), "i");import config from "./config.json" with { type: "json" };Worth knowing as the standardized form of a thing bundlers faked for years.
Math.f16round, Float16Array — mention-only, relevant to graphics/ML-adjacent roles.
Object.groupBy" is the strongest possible framing.structuredClone doesn't clone functions (details here); iterator helpers don't exist on plain arrays' values in old runtimes; Object.groupBy returns a null-prototype object.The ES2024 way to create a promise you settle from outside — and how to implement the deferred pattern it replaces.
map, filter, take, and drop directly on iterators (ES2025): lazy evaluation without loading everything into an array.