一、Promise基础概念
1.1 核心特性
Promise是ES6引入的异步编程解决方案,具有三大核心特性:
- 状态不可逆性:仅能从pending→fulfilled或pending→rejected单向转换
- 链式调用:通过then/catch串联异步操作
- 统一错误处理:catch集中捕获链式调用中的异常
1.2 基本结构
js
const fetchData = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
resolve('操作成功'); // 成功状态
// reject(new Error('操作失败')); // 失败状态
}, 1000);
});
fetchData.then(data => console.log(data)) // 成功回调
.catch(err => console.error(err)); // 错误处理
二、进阶应用场景
2.1 异步流程控制
串行请求(依赖前序结果)
js
function getUser(id) { return fetch(`/api/users/${id}`).then(res => res.json()); }
function getPosts(userId) { return fetch(`/api/posts/${userId}`).then(res => res.json()); } // 自动等待前序请求完成
getUser(1).then(user => getPosts(user.id)).then(posts => console.log(posts)).catch(console.error);
并行请求(Promise.all)
js
Promise.all([ fetch('/api/users').then(res => res.json()),
fetch('/api/posts').then(res => res.json()) ]).then(([users, posts]) => {
console.log('用户数据:', users);
console.log('帖子数据:', posts);
});
2.2 错误处理机制
穿透式错误捕获
js
fetchData.then(processData).then(saveData).catch(err => {
console.error('流程中断:', err);
return Promise.reject(err); // 保持错误传递
});
2.3 状态管理进阶
手动状态控制(模拟加载状态)
js
class DataLoader {
constructor() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;});
}
load() {
// 模拟异步加载
setTimeout(() => {
this.resolve(loadedData);}, 1000);
}
cancel() {
this.reject(new Error('操作取消'));
} }
三、企业级实践方案
3.1 请求封装示例
js
class APIClient {
constructor(baseURL) { this.baseURL = baseURL; }
request(options) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(options.method, `${this.baseURL}${options.path}`);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.response));
} else {
reject(new Error(`请求失败: ${xhr.status}`));
} };
xhr.onerror = () => reject(new Error('网络错误'));
xhr.send(options.data || null);});
} }
// 使用示例
const client = new APIClient('https://api.example.com');
client.request({ method: 'GET', path: '/users' }) .then(users => console.log(users)) .catch(console.error);
3.2 性能优化策略
请求池化技术
js
class RequestPool {
constructor(maxConcurrent = 5) {
this.queue = [];
this.running = 0;
this.max = maxConcurrent;
}
add(promise) {
this.queue.push(promise);
if (this.running < this.max) {
this._runNext();
}
return promise; }
_runNext() {
if (this.queue.length === 0) return;
const task = this.queue.shift();
task.finally(() => {
this.running--;
this._runNext();
});
this.running++; } }
// 使用示例
const pool = new RequestPool(3);
for (let i = 0; i < 8; i++) {
pool.add(fetch(`/api/data/${i}`));
}
四、常见问题解析
4.1 执行顺序陷阱
js
console.log(1);
new Promise(resolve => {
console.log(2);
setTimeout(() => {
console.log('timer');
resolve(); }, 0);
console.log(3); }) .then(() => console.log(4));
console.log(5); // 输出顺序: 1 → 2 → 3 → 5 → timer → 4