# 一次性复习Promise上所有方法的实现原理
### 引言
Promise是JavaScript异步编程的核心工具之一,它的出现极大地提升了代码的可读性和可控性。本文将围绕Promise对象的所有方法展开,通过详尽的解析和代码实现,带你一次性复习Promise的构造函数、静态方法以及实例方法的底层实现原理。
### 一、Promise构造函数
Promise本质上是一个对象,用于表示一个异步操作的结果。创建一个新的Promise,需要传入一个executor函数,该函数接收两个回调函数resolve和reject。
```javascript
class Promise {
constructor(executor) {
let self = this;
this.status = 'pending'; // 初始状态为pending
this.value = undefined; // 成功时的值
this.reason = undefined; // 失败时的原因
// executor函数立即执行
try {
executor(
(value) => {
// resolve回调
if (self.status === 'pending') {
self.status = 'fulfilled';
self.value = value;
self.resolveCallbacks.forEach(cb => cb(value));
}
},
(reason) => {
// reject回调
if (self.status === 'pending') {
self.status = 'rejected';
self.reason = reason;
self.rejectCallbacks.forEach(cb => cb(reason));
}
}
);
} catch (e) {
// 如果executor执行过程中抛出异常,则直接进入rejected状态
if (self.status === 'pending') {
self.status = 'rejected';
self.reason = e;
self.rejectCallbacks.forEach(cb => cb(e));
}
}
// 存储resolve和reject的回调函数
this.resolveCallbacks = [];
this.rejectCallbacks = [];
}
}
```
### 二、Promise静态方法
#### 2.1 Promise.resolve()
Promise.resolve方法用于将现有值转换为Promise对象。
```javascript
Promise.resolve = function(value) {
return new Promise((resolve) => {
resolve(value);
});
};
```
#### 2.2 Promise.reject()
Promise.reject方法用于生成一个状态为rejected的Promise对象。
```javascript
Promise.reject = function(reason) {
return new Promise((_, reject) => {
reject(reason);
});
};
```
#### 2.3 Promise.all()
Promise.all方法用于等待一组Promise全部变为fulfilled状态后才执行回调。
```javascript
Promise.all = function(promises) {
return new Promise((resolve, reject) => {
let resolvedCount = 0;
const values = new Array(promises.length);
promises.forEach((promise, index) => {
promise.then(
(value) => {
resolvedCount++;
values[index] = value;
if (resolvedCount === promises.length) {
resolve(values);
}
},
(reason) => reject(reason)
);
});
});
};
```
#### 2.4 Promise.race()
Promise.race方法用于等待一组Promise中的第一个变为fulfilled或rejected状态后就执行回调。
```javascript
Promise.race = function(promises) {
return new Promise((resolve, reject) => {
promises.forEach((promise) => {
promise.then(resolve, reject);
});
});
};
```
### 三、Promise实例方法
#### 3.1 then()
then方法用于注册两个回调函数,分别对应Promise的成功和失败状态。
```javascript
Promise.prototype.then = function(onFulfilled, onRejected) {
let self = this;
let promise2;
if (typeof onFulfilled !== 'function') {
onFulfilled = (value) => value;
}
if (typeof onRejected !== 'function') {
onRejected = (reason) => { throw reason; };
}
if (self.status === 'pending') {
promise2 = new Promise((resolve, reject) => {
self.resolveCallbacks.push((value) => {
try {
let x = onFulfilled(value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
self.rejectCallbacks.push((reason) => {
try {
let x = onRejected(reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
});
});
} else if (self.status === 'fulfilled') {
setTimeout(() => {
try {
let x = onFulfilled(self.value);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
} else if (self.status === 'rejected') {
setTimeout(() => {
try {
let x = onRejected(self.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (error) {
reject(error);
}
}, 0);
}
return promise2;
};
// 解析Promise链
function resolvePromise(promise2, x, resolve, reject) {
// 状态确定、循环引用、非对象或已承诺情况的处理
// (这部分详细代码因篇幅原因省略,请查阅Promise A+规范)
}
```
#### 3.2 catch()
catch方法是then方法的特殊情况,用于捕获Promise的拒绝原因。
```javascript
Promise.prototype.catch = function(onRejected) {
return this.then(null, onRejected);
};
```
### 结语
通过这次对Promise所有方法的实现原理复习,希望你能深入理解Promise的运作机制,进一步提升在实际开发中的异步编程能力。记住,掌握Promise的核心逻辑,有助于我们更好地驾驭JavaScript的异步世界。