Question presented to candidate: "Promise.any takes an array of promises and resolves as soon as ANY one of them fulfills — it only rejects if every single one of them fails, and in that case it rejects with a special AggregateError containing all the individual failure reasons. Implement a polyfill for it. What happens if a rejection genuinely arrives before a fulfillment does? And what should the order of the errors be inside the AggregateError?"
What a strong answer should cover:
- The outer promise resolves the instant ANY item fulfills — a rejection arriving first, even much faster than the eventual winner, must not affect the outcome at all.
- The outer promise only rejects once EVERY item has rejected; that is the opposite failure condition from
Promise.all. - The rejection reason is a real
AggregateError, a built-inErrorsubclass added specifically for this purpose, whose.errorsproperty is an array of every individual rejection reason. - That
.errorsarray should preserve INPUT order (which promise was originally where), not the order the rejections actually happened to arrive in — this is the exact same indexing disciplinePromise.all's polyfill needs for its results array. - An empty input array is a genuine edge case: it must reject immediately with an
AggregateErrorcontaining zero errors, since there is nothing that could possibly fulfill. AggregateError's constructor signature isnew AggregateError(errorsIterable, message)— the errors come first, the message second, the reverse of what some engineers expect from plainError.
Clarifying questions expected:
- "Should the polyfill construct a real AggregateError, or is a plain Error with an attached .errors array acceptable if the environment predates AggregateError?" — a real interview-worthy compatibility question, since AggregateError is a newer addition than Promise itself.
- "Do all the rejection reasons need to be captured even after the first one arrives, or can we stop tracking once we know the outer promise cannot possibly succeed?" — clarifies whether early-exit optimizations are in scope.
Code / implementation expected: Yes — a full, runnable polyfill plus a real test proving a fulfillment wins over a faster rejection, and that AggregateError.errors preserves input order.