Technical Interview Challenge: The "Micro-Runtime" Promise Engine
Context
You are part of a team building a specialized, lightweight JavaScript runtime for edge computing. To minimize the binary size, you’ve decided to exclude the full V8 engine and implement core language features manually. One of the most critical components is the Asynchronous Orchestration Layer.
You are tasked with building a custom Promise implementation that adheres to the Promises/A+ behavioral standards, ensuring that asynchronous tasks are handled predictably without blocking the main execution thread.
Problem Statement
Implement a class MyPromise that replicates the core functionality of the native JavaScript Promise. Your implementation must manage state transitions and coordinate the execution of dependent callbacks via the Microtask Queue.
Requirements:
State Management: The promise must transition from
PENDINGto eitherFULFILLEDorREJECTED. Once settled, the state and value must become immutable.Executor Execution: The constructor must take an
executorfunction that receivesresolveandrejectarguments.Asynchronous Chaining:
Implement
.then(onFulfilled, onRejected), which returns a newMyPromiseto allow for chaining.Handlers passed to
.thenmust be executed asynchronously using the microtask queue (e.g.,queueMicrotask), even if the promise is already settled.
Error Handling: Implement
.catch(onRejected)as a shorthand for error management.Value Forwarding: If a
.thenhandler returns a value, the next promise in the chain should resolve with that value. If it returns anotherMyPromise, the chain must wait for that promise to settle before continuing.
Example Use Cases
Example 1: Basic Resolution & Chaining
JavaScript
const p = new MyPromise((resolve) => {
resolve(10);
});
p.then(val => val * 2)
.then(val => console.log(val));
// Expected Output (Async): 20Example 2: Asynchronous Delay
JavaScript
new MyPromise((resolve) => {
setTimeout(() => resolve("Data Loaded"), 100);
})
.then(data => data.toUpperCase())
.then(result => console.log(result));
// Expected Output (After 100ms): "DATA LOADED"Example 3: Error Propagation
JavaScript
new MyPromise((_, reject) => {
reject(new Error("Network Failed"));
})
.catch(err => console.error(err.message));
// Expected Output: "Network Failed"Interview Evaluation Criteria
The "Zalgo" Test: Does your implementation guarantee that
.thencallbacks always run asynchronously, even for immediate resolutions?Chainability: Does every call to
.thenreturn a unique promise instance?State Locking: Does your implementation prevent a promise from changing its value once it has been resolved or rejected?
Microtask Awareness: Do you correctly distinguish between the Macrotask queue (
setTimeout) and the Microtask queue (queueMicrotask)?