手写个promise
时间: 2025-04-15 15:18:50 浏览: 25
<think>好的,我需要帮助用户手动实现JavaScript的Promise类。根据用户提供的引用内容,特别是引用3中的代码示例,用户可能已经了解了一些基础结构,比如状态管理、构造函数和状态改变方法。但还需要更详细的步骤来完整实现Promise的功能。
首先,我需要回顾Promise的核心特性:三种状态(pending, fulfilled, rejected)、then方法的链式调用、异步执行、错误处理、静态方法如resolve、reject、all、race等。
用户提供的引用3中的代码已经展示了构造函数和状态管理的基本结构,但缺少then方法的实现和静态方法。引用2提到了all方法和resolve方法的实现,这可能对后续步骤有帮助。
接下来,我需要分步骤构建Promise类:
1. **状态管理**:确保状态只能从pending转变为fulfilled或rejected,且不可逆。引用3中的#changeState方法处理了这一点,但代码中的条件判断可能有误,应该是如果状态不是pending才返回,而不是如果状态是pending才返回。需要检查并修正。
2. **执行器函数**:构造函数中的executor会立即执行,并传入resolve和reject函数。需要注意处理executor中的同步和异步错误,比如用try-catch包裹executor的执行,并在出错时调用reject。
3. **then方法的实现**:这是最复杂的部分。then方法需要返回新的Promise,处理回调的异步执行,以及链式调用。需要考虑回调函数返回普通值或Promise的情况,并处理穿透(值传递)。
4. **异步处理**:根据Promise规范,then方法的回调需要异步执行。可以使用setTimeout或queueMicrotask来模拟。
5. **静态方法**:实现resolve、reject、all、race等方法。引用2中的resolve和all方法可以作为参考,但需要整合到类中作为静态方法。
在实现过程中,可能会遇到如何处理多个then回调、错误冒泡、以及链式调用的细节问题。例如,当then中的回调返回一个新的Promise时,需要等待其状态改变后再决定链式Promise的状态。
此外,需要测试代码的正确性,例如确保resolve后不会执行reject,处理异步任务,以及链式调用中值的传递。
最后,根据用户提供的引用内容,可能需要引用相关的实现部分,并在解释时标注引用来源,如引用[^1]、[^2]、[^3]。</think>### 手动实现 JavaScript Promise 类的分步解析
#### 一、基础结构搭建
1. **定义三种状态常量**
```javascript
const PENDING = 'pending';
FULFILLED = 'fulfilled';
REJECTED = 'rejected';
```
2. **创建构造函数**
包含状态、结果、回调队列(用于异步处理),引用自基础实现结构[^3]:
```javascript
class MyPromise {
#state = PENDING;
#result = undefined;
#callbacks = []; // 回调队列
constructor(executor) {
const resolve = (value) => this.#changeState(FULFILLED, value);
const reject = (reason) => this.#changeState(REJECTED, reason);
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
}
```
3. **实现状态转换方法**
修正原条件判断逻辑错误:
```javascript
#changeState(state, result) {
if (this.#state !== PENDING) return; // 修正后的条件判断
this.#state = state;
this.#result = result;
this.#runCallbacks(); // 状态变更后执行回调
}
```
#### 二、核心 then 方法实现
1. **方法签名定义**
```javascript
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
// 包装回调函数处理逻辑
const callback = () => {
try {
const handler = this.#state === FULFILLED ? onFulfilled : onRejected;
// 实现值穿透
if (typeof handler !== 'function') {
this.#state === FULFILLED ? resolve(this.#result) : reject(this.#result);
return;
}
const nextValue = handler(this.#result);
// 处理返回 Promise 的情况
if (nextValue instanceof MyPromise) {
nextValue.then(resolve, reject);
} else {
resolve(nextValue);
}
} catch (err) {
reject(err);
}
};
// 异步执行
if (this.#state === PENDING) {
this.#callbacks.push(callback);
} else {
queueMicrotask(callback); // 使用微任务实现
}
});
}
```
2. **回调队列执行方法**
```javascript
#runCallbacks() {
while (this.#callbacks.length) {
const cb = this.#callbacks.shift();
queueMicrotask(cb); // 保证异步执行顺序
}
}
```
#### 三、静态方法实现
1. **MyPromise.resolve**
```javascript
static resolve(value) {
if (value instanceof MyPromise) return value;
return new MyPromise(resolve => resolve(value));
}
```
2. **MyPromise.reject**
```javascript
static reject(reason) {
return new MyPromise((_, reject) => reject(reason));
}
```
3. **MyPromise.all**(引用自all方法实现思路[^2])
```javascript
static all(promises) {
return new MyPromise((resolve, reject) => {
const results = [];
let completed = 0;
const checkCompletion = () => {
if (completed === promises.length) {
resolve(results);
}
};
promises.forEach((p, i) => {
MyPromise.resolve(p).then(
value => {
results[i] = value;
completed++;
checkCompletion();
},
reject // 任一失败立即拒绝
);
});
});
}
```
#### 四、错误处理增强
1. **实现catch方法**
```javascript
catch(onRejected) {
return this.then(null, onRejected);
}
```
2. **finally方法实现**
```javascript
finally(callback) {
return this.then(
value => MyPromise.resolve(callback()).then(() => value),
reason => MyPromise.resolve(callback()).then(() => { throw reason })
);
}
```
#### 五、使用示例
```javascript
// 测试链式调用
new MyPromise((resolve) => resolve(10))
.then(v => v * 2)
.then(console.log); // 输出20
// 测试异步执行
new MyPromise(resolve => setTimeout(() => resolve(1), 100))
.then(v => v + 2)
.then(console.log); // 3
// 测试静态方法
MyPromise.all([
MyPromise.resolve(1),
new MyPromise(resolve => setTimeout(() => resolve(2), 500)),
3 // 非Promise值
]).then(console.log); // [1, 2, 3]
```
阅读全文
相关推荐



















