Understanding and Implementing JavaScript Promise: From Basic Construction to State Management
This article walks developers through building a functional JavaScript Promise from scratch, starting with a minimal callback list, adding chainable then calls, introducing a micro‑task delay to handle early resolves, and finally implementing state management so callbacks added after fulfillment still execute correctly.
Many developers learn the syntax of Promise without grasping its underlying mechanism. This article series explains Promise implementation step‑by‑step, using diagrams, examples, and animations to achieve a deep understanding.
The series is divided into four chapters:
Basic implementation of Promise
Chainable then calls
Adding an asynchronous delay mechanism
Introducing state management (pending, fulfilled, rejected)
1. Basic version
The simplest Promise stores callbacks in an array and invokes them when resolve is called.
//极简的实现
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
}
_resolve(value) {
this.callbacks.forEach(fn => fn(value));
}
}
//Promise应用
let p = new Promise(resolve => {
setTimeout(() => {
console.log('done');
resolve('5秒');
}, 5000);
}).then(tip => {
console.log(tip);
});This code shows how then registers a callback that runs after the asynchronous operation finishes.
2. Chainable then
To enable chaining, then returns the Promise instance itself.
//极简的实现+链式调用
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
return this; // enable chaining
}
_resolve(value) {
this.callbacks.forEach(fn => fn(value));
}
}
let p = new Promise(resolve => {
setTimeout(() => {
console.log('done');
resolve('5秒');
}, 5000);
}).then(tip => {
console.log('then1', tip);
}).then(tip => {
console.log('then2', tip);
});Now multiple then calls can be written in a single statement.
3. Adding an asynchronous delay (micro‑task queue)
When resolve runs before any then registration, callbacks are missed. Wrapping the callback execution in setTimeout defers it to the end of the task queue, guaranteeing that all then handlers are already registered.
//极简的实现+链式调用+延迟机制
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
return this;
}
_resolve(value) {
setTimeout(() => {
this.callbacks.forEach(fn => fn(value));
});
}
}With this change, even synchronous resolves trigger the callbacks after the current call stack.
Example of a synchronous resolve that previously lost then callbacks:
//同步执行了resolve
let p = new Promise(resolve => {
console.log('同步执行');
resolve('同步执行');
}).then(tip => {
console.log('then1', tip);
}).then(tip => {
console.log('then2', tip);
});
setTimeout(() => {
p.then(tip => {
console.log('then3', tip);
});
});After adding the delay, then1 and then2 are printed, but then3 still does not run because it is added after the promise is already fulfilled.
4. Introducing state management
To solve the remaining issue, the Promise tracks its state ( pending, fulfilled, rejected) and stores the resolved value. When then is called after fulfillment, the callback is executed immediately with the stored value.
//极简的实现+链式调用+延迟机制+状态
class Promise {
callbacks = [];
state = 'pending'; // 增加状态
value = null; // 保存结果
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
if (this.state === 'pending') {
this.callbacks.push(onFulfilled);
} else {
onFulfilled(this.value);
}
return this;
}
_resolve(value) {
this.state = 'fulfilled'; // 改变状态
this.value = value; // 保存结果
this.callbacks.forEach(fn => fn(value));
}
}With state handling, callbacks added after resolution are still executed, completing a functional Promise implementation.
The article also includes diagrams illustrating the flow of each version and notes that only the fulfilled branch is implemented so far; future chapters will add rejected handling.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
vivo Internet Technology
Sharing practical vivo Internet technology insights and salon events, plus the latest industry news and hot conferences.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
