Promise 概述
Promise 是 JavaScript 中的一个异步编程解决方案,它代表了一个最终可能完成(或失败)及其结果值的异步操作。Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。Promise 一旦从 pending 状态变为 fulfilled 或 rejected 状态,状态就不会再改变,即 Promise 的状态是不可逆的。
Promise 的基本使用
1. 创建 Promise
使用 new Promise(executor)
构造函数来创建一个 Promise 实例,executor
函数接受两个参数:resolve
和 reject
,它们是两个函数,由 JavaScript 引擎提供,分别用于将 Promise 的状态从 pending 变为 fulfilled 或 rejected。
javascript
let promise = new Promise(function(resolve, reject) {
// 异步操作
if (/* 异步操作成功 */) {
resolve(value); // 将 Promise 的状态从 pending 变为 fulfilled,并将结果作为参数传递
} else {
reject(error); // 将 Promise 的状态从 pending 变为 rejected,并将错误作为参数传递
}
});
2. 使用 Promise
Promise 提供了 .then()
、.catch()
和 .finally()
方法用于处理异步操作的结果或错误。
.then(onFulfilled, onRejected)
:当 Promise 变为 fulfilled 或 rejected 时,相应的函数会被调用。.catch(onRejected)
:用于指定发生错误时的回调函数,是.then(null, onRejected)
的语法糖。.finally(onFinally)
:无论 Promise 最终状态如何,都会执行该函数。
javascript
promise.then(function(value) {
// 处理成功的情况
}).catch(function(error) {
// 处理错误的情况
}).finally(function() {
// 无论成功或失败都会执行
});
手写 Promise
下面是一个简化版的 Promise 实现,主要实现了基本的状态管理和 .then()
方法。
javascript
function MyPromise(executor) {
this.status = 'pending'; // 初始状态
this.value = undefined; // 存放异步操作的结果
this.reason = undefined; // 存放错误原因
this.onFulfilledCallbacks = []; // 存放成功的回调函数
this.onRejectedCallbacks = []; // 存放失败的回调函数
// 更改 Promise 的状态
function resolve(value) {
if (this.status === 'pending') {
this.status = 'fulfilled';
this.value = value;
this.onFulfilledCallbacks.forEach(fn => fn());
}
}
function reject(reason) {
if (this.status === 'pending') {
this.status = 'rejected';
this.reason = reason;
this.onRejectedCallbacks.forEach(fn => fn());
}
}
// 捕获 executor 执行器中的错误
try {
executor(resolve.bind(this), reject.bind(this));
} catch (e) {
reject.call(this, e);
}
// 实现 then 方法
MyPromise.prototype.then = function(onFulfilled, onRejected) {
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason; };
return new MyPromise((resolve, reject) => {
if (this.status === 'fulfilled') {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(resolve, reject, x);
} catch (e) {
reject(e);
}
});
} else if (this.status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(resolve, reject, x);
} catch (e) {
reject(e);
}
});
} else {
this.onFulfilledCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(resolve, reject, x);
} catch (e) {
reject(e);
}
});
});
this.onRejectedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(resolve, reject, x);
} catch (e) {
reject(e);
}
});
});
}
});
};
// 辅助函数,处理 then 或 catch 中的返回值
function resolvePromise(resolve, reject, x) {
// ... 省略了一些复杂的处理逻辑,如处理 x 为 Promise 的情况
if (x !== promise2) { // 避免自引用
if (x instanceof MyPromise) {
x.then(resolve, reject);
} else {
resolve(x);
}
}
}
}
注意:上面的代码是一个非常简化的版本,省略了很多重要的细节和错误处理逻辑(比如处理 x 为 Promise 的情况),以及 .catch()
和 .finally()
方法的实现。在实际应用中,Promise 的实现要复杂得多,并且需要处理各种边界情况和错误。