实现Promise的resolve方法
手写实现Promise.resolve静态方法,理解Promise值的包装和转换机制
问题
Promise.resolve() 是 Promise 的一个静态方法,用于将给定的值转换为一个 Promise 对象。需要实现这个方法,处理以下几种情况:
- 如果参数是 Promise 实例,直接返回该实例
- 如果参数是 thenable 对象(具有 then 方法),将其转换为 Promise
- 如果参数是普通值,返回一个状态为 fulfilled 的 Promise
- 如果没有参数,返回一个状态为 fulfilled 的 Promise(值为 undefined)
解答
/**
* 实现 Promise.resolve 静态方法
* @param {*} value - 要转换为 Promise 的值
* @returns {Promise} 返回一个 Promise 对象
*/
Promise.myResolve = function(value) {
// 情况1: 如果参数是 Promise 实例,直接返回
if (value instanceof Promise) {
return value;
}
// 情况2: 如果是 thenable 对象(具有 then 方法)
if (value !== null && (typeof value === 'object' || typeof value === 'function')) {
if (typeof value.then === 'function') {
return new Promise((resolve, reject) => {
// 调用 thenable 对象的 then 方法
value.then(resolve, reject);
});
}
}
// 情况3: 普通值或无参数,返回一个 fulfilled 状态的 Promise
return new Promise((resolve) => {
resolve(value);
});
};
使用示例
// 示例1: 传入普通值
Promise.myResolve(42).then(value => {
console.log(value); // 输出: 42
});
// 示例2: 传入 Promise 实例
const p1 = new Promise(resolve => resolve('hello'));
const p2 = Promise.myResolve(p1);
console.log(p1 === p2); // 输出: true(返回同一个实例)
// 示例3: 传入 thenable 对象
const thenable = {
then: function(resolve, reject) {
setTimeout(() => resolve('thenable value'), 1000);
}
};
Promise.myResolve(thenable).then(value => {
console.log(value); // 1秒后输出: thenable value
});
// 示例4: 无参数
Promise.myResolve().then(value => {
console.log(value); // 输出: undefined
});
// 示例5: 传入对象
Promise.myResolve({ name: 'Alice', age: 25 }).then(value => {
console.log(value); // 输出: { name: 'Alice', age: 25 }
});
// 示例6: 链式调用
Promise.myResolve(10)
.then(value => value * 2)
.then(value => value + 5)
.then(value => {
console.log(value); // 输出: 25
});
关键点
-
类型判断优先级:首先判断是否为 Promise 实例,然后判断是否为 thenable 对象,最后作为普通值处理
-
Promise 实例直接返回:当参数本身就是 Promise 时,直接返回该实例,避免不必要的包装
-
thenable 对象处理:对于具有 then 方法的对象,需要创建新的 Promise 并调用其 then 方法,实现状态的正确传递
-
类型检查的严谨性:在检查 thenable 对象时,需要先确保值不为 null,且为对象或函数类型
-
普通值的包装:对于普通值(包括 undefined),创建一个新的 Promise 并立即 resolve
-
与原生方法的一致性:实现的行为应与原生
Promise.resolve()保持一致,确保在各种场景下都能正确工作
目录