前言
JavaScript Promise 是一种用于异步编程的重要解决方案,在现代 JavaScript 开发中被广泛使用。Promise的特点是可以避免回调地狱(callback hell),提供更清晰和可读的代码结构,使得异步操作更加简洁和易于理解。在本文中,我们将学习手写一个简单的Promise实现。
实现 Promise 构造函数
在实现自定义的Promise之前,我们首先需要了解Promise的基本结构。Promise的构造函数需要接受一个executor函数作为参数,该函数会立即执行。executor函数接受两个参数:resolve和reject。当异步操作成功时,调用resolve方法;当异步操作失败时,调用reject方法。
function MyPromise(executor) {
this.status = 'pending'; // 初始状态为pending
this.value = undefined; // 异步操作返回的结果
this.onResolvedCallbacks = []; // 存储成功的回调函数
this.onRejectedCallbacks = []; // 存储失败的回调函数
const resolve = value => {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onResolvedCallbacks.forEach(callback => callback(this.value));
}
};
const reject = reason => {
if (this.status === 'pending') {
this.status = 'rejected';
this.value = reason;
this.onRejectedCallbacks.forEach(callback => callback(this.value));
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
实现 then 方法
Promise对象的 then 方法用于注册成功和失败的回调函数,并返回一个新的Promise对象,以支持链式调用。我们需要在MyPromise的原型上实现then方法,该方法接受两个参数:onFulfilled和onRejected,分别表示成功和失败的回调函数。
MyPromise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
const resolvePromise = (promise2, x, resolve, reject) => {
if (promise2 === x) {
return reject(new TypeError('循环引用'));
}
let called = false;
if (x instanceof MyPromise) {
if (x.status === 'pending') {
x.then(
value => resolvePromise(promise2, value, resolve, reject),
reason => reject(reason)
);
} else {
x.then(resolve, reject);
}
} else if (x != null && (typeof x === 'object' || typeof x === 'function')) {
try {
const then = x.then;
if (typeof then === 'function') {
then.call(
x,
value => {
if (called) return;
called = true;
resolvePromise(promise2, value, resolve, reject);
},
reason => {
if (called) return;
called = true;
reject(reason);
}
);
} else {
resolve(x);
}
} catch (error) {
if (called) return;
called = true;
reject(error);
}
} else {
resolve(x);
}
};
const promise2 = new MyPromise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
}
if (this.status === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
}
if (this.status === 'pending') {
this.onResolvedCallbacks.push(value => {
setTimeout(() => {
try {
const x = onFulfilled(value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
});
this.onRejectedCallbacks.push(reason => {
setTimeout(() => {
try {
const x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
});
}
});
return promise2;
};
总结
在以上代码中,我们成功实现了一个简单的Promise构造函数和then方法。尽管这只是一个最基本的实现,相比于内置的Promise来说还有很多功能是没有涵盖的,例如:Promise.all、Promise.race、Promise.catch等。但希望通过本文的介绍,你对Promise的实现原理和要点有了更深入的理解。手写Promise是提升JavaScript编程能力的一个很好的练习,你可以参考此实现并进行扩展,以深入理解Promise的各种用法和特性。