返回
从手写 Promise 来理解Promise 的方法
前端
2024-01-01 07:56:07
前言
在 JavaScript 中,我们经常会遇到异步编程的情况,比如发送 HTTP 请求、读取文件、设置定时器等。为了处理这些异步操作,我们需要一种机制来管理和等待这些操作的结果。Promise 就是一种这样的机制,它允许我们以同步的方式编写异步代码。
手写 Promise
在学习 Promise 的方法之前,我们先来手写一个 Promise。这将帮助我们更好地理解 Promise 的工作原理。
class Promise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
// 立即执行executor函数,将Promise的状态从pending变为fulfilled或rejected
try {
executor(this.resolve.bind(this), this.reject.bind(this));
} catch (err) {
this.reject(err);
}
}
// 将Promise的状态从pending变为fulfilled,并执行onFulfilledCallbacks中的回调函数
resolve(value) {
if (this.state !== 'pending') {
return;
}
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((callback) => callback(value));
}
// 将Promise的状态从pending变为rejected,并执行onRejectedCallbacks中的回调函数
reject(reason) {
if (this.state !== 'pending') {
return;
}
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((callback) => callback(reason));
}
// 为Promise添加一个onFulfilled回调函数,当Promise的状态变为fulfilled时执行该函数
then(onFulfilled, onRejected) {
// 如果onFulfilled不是函数,则忽略它
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => value;
// 如果onRejected不是函数,则忽略它
onRejected = typeof onRejected === 'function' ? onRejected : (reason) => { throw reason; };
// 创建一个新的Promise对象
const newPromise = new Promise((resolve, reject) => {
// 根据Promise的状态,执行相应的回调函数
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const result = onFulfilled(this.value);
resolve(result);
} catch (err) {
reject(err);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const result = onRejected(this.reason);
resolve(result);
} catch (err) {
reject(err);
}
}, 0);
} else {
// 如果Promise的状态还是pending,则将onFulfilled和onRejected回调函数添加到相应的数组中
this.onFulfilledCallbacks.push((value) => {
setTimeout(() => {
try {
const result = onFulfilled(value);
resolve(result);
} catch (err) {
reject(err);
}
}, 0);
});
this.onRejectedCallbacks.push((reason) => {
setTimeout(() => {
try {
const result = onRejected(reason);
resolve(result);
} catch (err) {
reject(err);
}
}, 0);
});
}
});
// 返回新的Promise对象