一、基本概念
- Promise 是异步编程的解决方案,用于处理异步操作
- 代表一个未来才会知道结果的事件(通常是异步操作)
- 状态一旦改变就不会再变
二、三种状态
- pending(进行中) - 初始状态
- fulfilled(已成功) - 操作成功完成
- rejected(已失败) - 操作失败
状态转换:
pending → fulfilled 或 pending → rejected
三、基本用法
javascript
javascript
const promise = new Promise((resolve, reject) => {
// 异步操作
if (/* 成功 */) {
resolve(value); // 状态变为fulfilled
} else {
reject(error); // 状态变为rejected
}
});
promise.then(
value => { /* 成功处理 */ },
error => { /* 失败处理 */ }
);
四、实例方法
1. then() - 主要处理方法
javascript
arduino
promise.then(
onFulfilled, // 成功回调
onRejected // 失败回调(可选)
);
2. catch() - 错误处理
javascript
ini
promise.catch(error => {
// 处理错误(等同于then(null, onRejected))
});
3. finally() - 最终执行
javascript
dart
promise.finally(() => {
// 无论成功失败都会执行
});
五、静态方法
1. Promise.resolve() - 创建已完成的Promise
javascript
ini
Promise.resolve(value);
2. Promise.reject() - 创建已拒绝的Promise
javascript
ini
Promise.reject(reason);
3. Promise.all() - 所有完成才完成
javascript
ini
Promise.all([p1, p2, p3])
.then(values => { /* 所有都成功 */ })
.catch(error => { /* 有一个失败就失败 */ });
4. Promise.race() - 竞速,第一个完成/拒绝的
javascript
ini
Promise.race([p1, p2, p3])
.then(value => { /* 第一个完成的 */ });
5. Promise.allSettled() - 所有都完成(无论成功失败)
javascript
ini
Promise.allSettled([p1, p2, p3])
.then(results => { /* 所有promise都已完成 */ });
6. Promise.any() - 任意一个成功就成功
javascript
ini
Promise.any([p1, p2, p3])
.then(value => { /* 第一个成功的 */ });
六、链式调用
javascript
dart
promise
.then(value => { /* 第一步 */ })
.then(value => { /* 第二步 */ })
.catch(error => { /* 错误处理 */ })
.finally(() => { /* 清理 */ });
特点:
- 每个
then()返回新的Promise - 可以传递值给下一个
then() - 错误会沿着链向后传递
七、错误处理最佳实践
javascript
scss
// 推荐:使用catch处理错误
promise
.then(handleSuccess)
.catch(handleError);
// 避免:then中第二个参数和catch混用
promise
.then(handleSuccess, handleError) // 可能无法捕获then中的错误
.catch(handleOtherError); // 可能不会执行
八、与async/await结合
javascript
csharp
async function fetchData() {
try {
const result = await promise;
// 处理结果
} catch (error) {
// 处理错误
}
}
九、优缺点
优点:
- 解决回调地狱,代码更清晰
- 更好的错误处理机制
- 支持链式调用
- 提供了丰富的静态方法
缺点:
- 无法取消Promise
- 错误需要显式捕获
- 状态单一,不能监听进度
十、常见使用场景
- AJAX请求 - 替代XMLHttpRequest
- 定时器操作 - setTimeout封装
- 文件读取 - Node.js文件操作
- 数据库操作 - 异步查询
- 多个异步操作协调 - 使用Promise.all等
十一、注意事项
- Promise内部错误会被吞没,必须使用catch
- Promise创建即执行,不能中途取消
- 状态不可逆,一旦改变无法回退
- then()中的错误需要显式处理
十二、现代JavaScript实践
javascript
javascript
// ES2020+ 推荐写法
const fetchUser = async (userId) => {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) throw new Error('Network error');
return await response.json();
} catch (error) {
console.error('Fetch failed:', error);
throw error; // 重新抛出
}
};
Promise是现代JavaScript异步编程的核心,虽然现在有async/await语法糖,但理解Promise是掌握JavaScript异步编程的基础。