手写promise
js
class MyPromise {
// 定义三种状态
static PENDING = 'pending';
static FULFILLED = 'fulfilled';
static REJECTED = 'rejected';
constructor(executor) {
// 初始状态为pending
this.status = MyPromise.PENDING;
// 存储成功的值
this.value = null;
// 存储失败的原因
this.reason = null;
// 存储成功的回调函数队列
this.onFulfilledCallbacks = [];
// 存储失败的回调函数队列
this.onRejectedCallbacks = [];
// 成功回调
const resolve = (value) => {
// 只有pending状态才能转换
if (this.status === MyPromise.PENDING) {
// 异步执行,模拟浏览器微任务
queueMicrotask(() => {
this.status = MyPromise.FULFILLED;
this.value = value;
// 执行所有成功回调
this.onFulfilledCallbacks.forEach(callback => callback(value));
});
}
};
// 失败回调
const reject = (reason) => {
// 只有pending状态才能转换
if (this.status === MyPromise.PENDING) {
// 异步执行,模拟浏览器微任务
queueMicrotask(() => {
this.status = MyPromise.REJECTED;
this.reason = reason;
// 执行所有失败回调
this.onRejectedCallbacks.forEach(callback => callback(reason));
});
}
};
try {
// 执行 executor 函数
executor(resolve, reject);
} catch (error) {
// 若执行过程中出错,直接reject
reject(error);
}
}
// then方法实现链式调用
then(onFulfilled, onRejected) {
// 处理onFulfilled和onRejected不是函数的情况
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => {
throw reason;
};
// 返回新的Promise以支持链式调用
return new MyPromise((resolve, reject) => {
// 处理当前状态为fulfilled的情况
if (this.status === MyPromise.FULFILLED) {
queueMicrotask(() => {
try {
// 执行成功回调并获取返回值
const result = onFulfilled(this.value);
// 解析返回值,如果是Promise则等待其完成
this.resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
}
// 处理当前状态为rejected的情况
if (this.status === MyPromise.REJECTED) {
queueMicrotask(() => {
try {
// 执行失败回调并获取返回值
const result = onRejected(this.reason);
// 解析返回值
this.resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
}
// 处理当前状态为pending的情况
if (this.status === MyPromise.PENDING) {
// 将回调存入队列,等待状态变更
this.onFulfilledCallbacks.push(() => {
try {
const result = onFulfilled(this.value);
this.resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push(() => {
try {
const result = onRejected(this.reason);
this.resolvePromise(result, resolve, reject);
} catch (error) {
reject(error);
}
});
}
});
}
// 解析then方法返回值
resolvePromise(result, resolve, reject) {
// 防止循环引用
if (result === this) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
// 如果返回值是Promise
if (result instanceof MyPromise) {
result.then(resolve, reject);
} else {
// 否则直接resolve
resolve(result);
}
}
// catch方法,用于捕获错误
catch(onRejected) {
return this.then(null, onRejected);
}
// finally方法,无论成功失败都会执行
finally(callback) {
return this.then(value => MyPromise.resolve(callback()).then(() => value), reason => MyPromise.resolve(callback()).then(() => {
throw reason;
}));
}
// 静态resolve方法
static resolve(value) {
if (value instanceof MyPromise) {
return value;
}
return new MyPromise(resolve => resolve(value));
}
// 静态reject方法
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
}
// 测试代码
console.log('开始测试');
// 基本用法测试
const promise = new MyPromise((resolve, reject) => {
console.log('执行executor');
setTimeout(() => {
resolve('成功的值');
// 测试失败情况
// reject(new Error('失败原因'));
}, 1000);
});
promise
.then(value => {
console.log('第一个then:', value);
return '第一个then返回值';
})
.then(value => {
console.log('第二个then:', value);
return new MyPromise(resolve => {
setTimeout(() => resolve('第二个then返回的Promise'), 1000);
});
})
.then(value => {
console.log('第三个then:', value);
// 测试错误抛出
// throw new Error('手动抛出错误');
return '完成';
})
.catch(error => {
console.log('捕获错误:', error.message);
})
.finally(() => {
console.log('finally执行');
});
console.log('测试结束');