Question presented to candidate: "You're given a legacy function like readFile(path, (err, data) => {...}) using Node's classic error-first callback convention. Write a real, generic helper that converts ANY such function into one that returns a Promise instead."
What a strong answer should cover:
- π Interview term: the error-first (Node-style) callback convention β the classic pattern this conversion targets: a callback's FIRST argument is either an
Error(on failure) ornull/undefined(on success), with subsequent arguments carrying the real result. - π Interview term: wrapping with
new Promiseβ the real, direct answer: construct anew Promise((resolve, reject) => { ... }), calling the original callback-based function INSIDE the executor, and inside that callback, callingreject(err)iferris truthy, otherwiseresolve(result). - π Interview term: the real, direct answer to the prompt β verified directly: a real, generic
promisify(fn)helper β written once, reusable for ANY error-first function, not hardcoded to one specific function β was verified correctlyresolveing on a real success case andrejecting on a real error case, matching the original callback's own real behavior exactly. - π Interview term: Node's own built-in
util.promisifyβ verified directly: Node's REAL, built-inutil.promisify()does the IDENTICAL conversion, confirmed producing the same real result as the hand-written version for the identical legacy function β a real, standard tool that makes hand-rolling this conversion unnecessary in Node code specifically. - A precise answer names the real, general SHAPE of the conversion:
(...args) => new Promise((resolve, reject) => fn(...args, (err, result) => err ? reject(err) : resolve(result)))β genuinely works for any function following the error-first convention, regardless of how many success-value arguments it has (with the honest caveat that a callback returning MULTIPLE success values needs a small, deliberate adjustment, since a Promise can only resolve with one value).
Clarifying questions expected:
- None β this is a definitional/technical question; writing a real, GENERIC helper (not a one-off hardcoded wrapper for a single function) is the strong signal.
Code / implementation expected: Yes β a real, generic promisify helper, verified working for both the success and error paths of a real legacy callback function, is the clearest, most convincing demonstration.