ES6手写Promise
使用ES6 class语法实现简易版的手写Promise 实现 then 链式调用、catch、finally、和静态方法resolve,reject,注释清晰,逻辑清晰
首先定义类的成员变量
这些都是Promise中需要用的状态和回调存储
class MyPromise {
// 定义 Promise 的三种状态
static REJECTED = "rejected";
static PENDING = "pending";
static FULFILLED = "fulfilled";
// 初始化值和状态
value = undefined;
status = MyPromise.PENDING;
// 用于存储对应状态的回调函数
onFulfilledCallbacks = [];
onRejectedCallbacks = [];
}
然后编写构造函数
/**
* 构造函数,用于创建一个 Promise 实例
* @param {function} execute - 执行器函数,接受 resolve 和 reject 两个参数
*/
constructor(execute) {
// 定义 resolve 函数,用于改变 Promise 状态为 fulfilled
const resolve = (value) => {
if (this.status === MyPromise.PENDING) {
this.value = value;
this.status = MyPromise.FULFILLED;
// 调用所有 fulfilled 状态的回调函数
this.onFulfilledCallbacks.forEach((fun) => fun(value));
}
};
// 定义 reject 函数,用于改变 Promise 状态为 rejected
const reject = (value) => {
if (this.status === MyPromise.PENDING) {
this.value = value;
this.status = MyPromise.REJECTED;
// 调用所有 rejected 状态的回调函数
this.onRejectedCallbacks.forEach((fun) => fun(value));
}
};
try {
// 执行传入的 execute 函数
execute(resolve, reject);
} catch (error) {
// 捕获到错误,调用 reject
reject(error);
}
}
然后实现then方法
then方法的作用是处理Promise并返回一个新的Promise对象实例,以便于进行链式调用,再返回的新Promise对象中要进行三种状态的判断。同时使用queueMicrotask 来排队执行,确保处理微任务逻辑的正确性
/**
* then 方法,用于处理 Promise 的结果
* @param {function} onFulfilled - fulfilled 状态的回调函数
* @param {function} onRejected - rejected 状态的回调函数
* @returns {MyPromise} 返回一个新的 Promise 实例
*/
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) => {
// 根据当前 Promise 的状态执行对应的回调函数
if (this.status === MyPromise.FULFILLED) {
try {
const result = onFulfilled(this.value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
} else if (this.status === MyPromise.REJECTED) {
try {
const result = onRejected(this.value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
} else {
// 如果状态是 pending,则将回调函数存储起来,等待状态改变
this.onFulfilledCallbacks.push((value) => {
try {
const result = onFulfilled(value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push((value) => {
try {
const result = onRejected(value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
});
}
});
}
注意then方法中回调成功的result可能又为一个promise对象,这时候需要进行链式调用 编写一个函数进行判断
/**
* 处理 Promise 结果的方法,确保结果正确处理
* @param {any} result - Promise 处理的结果
* @param {function} resolve - 用于改变新的 Promise 状态为 fulfilled
* @param {function} reject - 用于改变新的 Promise 状态为 rejected
*/
handlePromiseResult(result, resolve, reject) {
if (result instanceof MyPromise) {
// 如果结果是一个 Promise,则等待其状态改变后再做处理
result.then(resolve, reject);
} else {
// 否则直接改变状态为 fulfilled 并传递结果
resolve(result);
}
}
整体代码
/**
* MyPromise 类,用于实现 Promise 的基本功能
*/
class MyPromise {
// 定义 Promise 的三种状态
static REJECTED = "rejected";
static PENDING = "pending";
static FULFILLED = "fulfilled";
// 初始化值和状态
value = undefined;
status = MyPromise.PENDING;
// 用于存储对应状态的回调函数
onFulfilledCallbacks = [];
onRejectedCallbacks = [];
/**
* 构造函数,用于创建一个 Promise 实例
* @param {function} execute - 执行器函数,接受 resolve 和 reject 两个参数
*/
constructor(execute) {
// 定义 resolve 函数,用于改变 Promise 状态为 fulfilled
const resolve = (value) => {
if (this.status === MyPromise.PENDING) {
this.value = value;
this.status = MyPromise.FULFILLED;
// 调用所有 fulfilled 状态的回调函数
this.onFulfilledCallbacks.forEach((fun) => fun(value));
}
};
// 定义 reject 函数,用于改变 Promise 状态为 rejected
const reject = (value) => {
if (this.status === MyPromise.PENDING) {
this.value = value;
this.status = MyPromise.REJECTED;
// 调用所有 rejected 状态的回调函数
this.onRejectedCallbacks.forEach((fun) => fun(value));
}
};
try {
// 执行传入的 execute 函数
execute(resolve, reject);
} catch (error) {
// 捕获到错误,调用 reject
reject(error);
}
}
/**
* then 方法,用于处理 Promise 的结果
* @param {function} onFulfilled - fulfilled 状态的回调函数
* @param {function} onRejected - rejected 状态的回调函数
* @returns {MyPromise} 返回一个新的 Promise 实例
*/
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) => {
// 根据当前 Promise 的状态执行对应的回调函数
if (this.status === MyPromise.FULFILLED) {
try {
const result = onFulfilled(this.value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
} else if (this.status === MyPromise.REJECTED) {
try {
const result = onRejected(this.value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
} else {
// 如果状态是 pending,则将回调函数存储起来,等待状态改变
this.onFulfilledCallbacks.push((value) => {
try {
const result = onFulfilled(value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
});
this.onRejectedCallbacks.push((value) => {
try {
const result = onRejected(value);
// 使用 queueMicrotask 来排队执行,确保处理逻辑的正确性
queueMicrotask(() => {
this.handlePromiseResult(result, resolve, reject);
});
} catch (error) {
reject(error);
}
});
}
});
}
/**
* 处理 Promise 结果的方法,确保结果正确处理
* @param {any} result - Promise 处理的结果
* @param {function} resolve - 用于改变新的 Promise 状态为 fulfilled
* @param {function} reject - 用于改变新的 Promise 状态为 rejected
*/
handlePromiseResult(result, resolve, reject) {
if (result instanceof MyPromise) {
// 如果结果是一个 Promise,则等待其状态改变后再做处理
result.then(resolve, reject);
} else {
// 否则直接改变状态为 fulfilled 并传递结果
resolve(result);
}
}
/**
* catch 方法,用于处理 Promise 的错误
* @param {function} onRejected - rejected 状态的回调函数
* @returns {MyPromise} 返回一个新的 Promise 实例
*/
catch(onRejected) {
// 使用 then 方法处理错误,并添加一个空的 then 来处理返回值
return this.then(null, onRejected).then();
}
/**
* finally 方法,用于处理 Promise 的最终逻辑,无论结果如何
* @param {function} callback - 最终要执行的回调函数
* @returns {MyPromise} 返回一个新的 Promise 实例
*/
finally(callback) {
// 无论结果如何,都执行 callback 函数,然后根据原始结果继续处理
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) =>
MyPromise.reject(callback()).then(() => {
throw reason;
})
);
}
/**
* 静态方法 resolve,用于将一个值转换为 Promise 对象
* @param {any} value - 要转换的值
* @returns {MyPromise} 返回一个新的 Promise 实例,状态为 fulfilled
*/
static resolve(value) {
return new MyPromise((resolve, reject) => {
resolve(value);
});
}
/**
* 静态方法 reject,用于创建一个拒绝状态的 Promise 对象
* @param {any} reason - 拒绝的原因
* @returns {MyPromise} 返回一个新的 Promise 实例,状态为 rejected
*/
static reject(reason) {
return new MyPromise((resolve, reject) => {
reject(reason);
});
}
}
// 示例用法
const p = new MyPromise((resolve, reject) => {
console.log("task");
// 模拟一个异步任务,1 秒后 resolve
setTimeout(() => {
resolve("data");
}, 1000);
});
// 使用 then 方法处理 Promise 的结果
p.then((res) => {
console.log("res", res);
// 返回一个新的 Promise,模拟一个失败的情况
return new MyPromise((resolve, reject) => {
setTimeout(() => {
reject(res + "2222222222");
}, 1000);
});
})
.then((res2) => console.log("res2", res2)) // 这里不会被执行
.catch((e) => console.error("e", e)) // 捕获到错误并处理
.finally(() => {
console.log("finally"); // 无论结果如何都会执行
});