Promise
是 JavaScript 中用于处理异步操作的核心机制。它的实现原理基于 状态机 和 回调函数,通过封装异步操作的状态和结果,提供了一种更优雅的方式来处理异步代码。以下是 Promise
的实现原理详解:
1. Promise 的核心概念
-
状态:
Promise
有三种状态:- Pending(等待):初始状态,既不是成功也不是失败。
- Fulfilled(已完成):操作成功完成。
- Rejected(已拒绝):操作失败。
- 状态一旦改变,就不可逆(从
Pending
到Fulfilled
或Rejected
)。
-
值:
Promise
在Fulfilled
或Rejected
时会有一个对应的值(value
或reason
)。
-
链式调用:
- 通过
then
、catch
和finally
方法,可以实现链式调用。
- 通过
2. Promise 的基本实现
以下是 Promise
的简化实现,帮助理解其核心原理:
class MyPromise {
constructor(executor) {
this.state = 'pending'; // 初始状态
this.value = undefined; // 成功时的值
this.reason = undefined; // 失败时的原因
this.onFulfilledCallbacks = []; // 成功回调队列
this.onRejectedCallbacks = []; // 失败回调队列
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((fn) => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject); // 执行 executor
} catch (error) {
reject(error); // 捕获同步错误
}
}
then(onFulfilled, onRejected) {
if (this.state === 'fulfilled') {
onFulfilled(this.value);
} else if (this.state === 'rejected') {
onRejected(this.reason);
} else {
// 如果状态是 pending,将回调存入队列
this.onFulfilledCallbacks.push(() => onFulfilled(this.value));
this.onRejectedCallbacks.push(() => onRejected(this.reason));
}
}
}
3. Promise 的链式调用
Promise
的链式调用是通过 then
方法返回一个新的 Promise
实现的。以下是链式调用的实现:
then(onFulfilled, onRejected) {
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
resolvePromise
函数
resolvePromise
用于处理 then
方法返回的值(可能是 Promise
或其他值):
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
4. Promise 的异步执行
Promise
的回调函数(then
、catch
)是异步执行的,即使Promise
已经处于fulfilled
或rejected
状态。- 在实现中,使用
setTimeout
模拟异步行为。
5. Promise 的其他方法
catch
catch
是 then(null, onRejected)
的语法糖:
catch(onRejected) {
return this.then(null, onRejected);
}
finally
finally
无论 Promise
是成功还是失败都会执行:
finally(callback) {
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) => MyPromise.resolve(callback()).then(() => { throw reason; })
);
}
静态方法
Promise.resolve
:返回一个已完成的Promise
。Promise.reject
:返回一个已拒绝的Promise
。Promise.all
:等待所有Promise
完成。Promise.race
:返回第一个完成的Promise
。
6. 完整实现
以下是 Promise
的完整实现(简化版):
class MyPromise {
constructor(executor) {
this.state = 'pending';
this.value = undefined;
this.reason = undefined;
this.onFulfilledCallbacks = [];
this.onRejectedCallbacks = [];
const resolve = (value) => {
if (this.state === 'pending') {
this.state = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach((fn) => fn());
}
};
const reject = (reason) => {
if (this.state === 'pending') {
this.state = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach((fn) => fn());
}
};
try {
executor(resolve, reject);
} catch (error) {
reject(error);
}
}
then(onFulfilled, onRejected) {
const promise2 = new MyPromise((resolve, reject) => {
if (this.state === 'fulfilled') {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (this.state === 'rejected') {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
const x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
const x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
});
}
});
return promise2;
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(callback) {
return this.then(
(value) => MyPromise.resolve(callback()).then(() => value),
(reason) => MyPromise.resolve(callback()).then(() => { throw reason; })
);
}
static resolve(value) {
return new MyPromise((resolve) => resolve(value));
}
static reject(reason) {
return new MyPromise((resolve, reject) => reject(reason));
}
}
function resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise'));
}
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
总结
Promise
的核心是基于状态机和回调队列实现的。- 通过
then
方法实现链式调用,每次调用返回一个新的Promise
。 Promise
的回调是异步执行的,通过setTimeout
模拟。Promise
的实现还包括错误处理、静态方法(如resolve
、reject
)等。