1. Promise 基本概念
Promise 是一个代表异步操作最终完成或失败的对象。它有三种状态:
-
pending(进行中)
-
fulfilled(已成功)
-
rejected(已失败)
2. 基本用法
// 创建 Promise
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const random = Math.random();
if (random > 0.5) {
resolve('success');
} else {
reject('error');
}
}, 1000);
});
// 处理 Promise
promise
.then(result => console.log(result))
.catch(error => console.error(error))
.finally(() => console.log('完成'));
3. Promise 链式调用
// 链式处理示例
function step1() {
return new Promise(resolve => {
setTimeout(() => resolve('步骤1完成'), 1000);
});
}
function step2(data) {
return new Promise(resolve => {
setTimeout(() => resolve(data + ' -> 步骤2完成'), 1000);
});
}
step1()
.then(result => step2(result))
.then(finalResult => console.log(finalResult))
.catch(error => console.error(error));
4. Promise 静态方法
4.1 Promise.all()
// 并行执行多个 Promise
const promises = [
fetch('/api/users'),
fetch('/api/posts'),
fetch('/api/comments')
];
Promise.all(promises)
.then(([users, posts, comments]) => {
// 所有请求都成功完成
})
.catch(error => {
// 任一请求失败
});
4.2 Promise.race()
// 竞态处理
const timeout = new Promise((_, reject) =>
setTimeout(() => reject('timeout'), 5000)
);
const fetchData = fetch('/api/data');
Promise.race([fetchData, timeout])
.then(result => console.log(result))
.catch(error => console.error(error));
4.3 Promise.allSettled()
// 等待所有 Promise 完成(无论成功失败)
Promise.allSettled([
fetch('/api/1'),
fetch('/api/2'),
fetch('/api/3')
])
.then(results => {
results.forEach(result => {
if (result.status === 'fulfilled') {
console.log('成功:', result.value);
} else {
console.log('失败:', result.reason);
}
});
});
5. 实际应用场景
5.1 接口请求封装
class HttpClient {
async get(url) {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('Request failed:', error);
throw error;
}
}
}
5.2 图片加载
function loadImage(url) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`Failed to load image: ${url}`));
img.src = url;
});
}
5.3 延时函数
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// 使用示例
async function animation() {
console.log('开始');
await delay(1000);
console.log('1秒后');
await delay(2000);
console.log('再2秒后');
}
5.4 缓存控制
class Cache {
constructor() {
this.cache = new Map();
}
async get(key, fetchFn) {
if (this.cache.has(key)) {
return this.cache.get(key);
}
const data = await fetchFn();
this.cache.set(key, data);
return data;
}
}
5.5 并发控制
class RequestQueue {
constructor(maxConcurrent = 5) {
this.queue = [];
this.running = 0;
this.maxConcurrent = maxConcurrent;
}
async add(request) {
if (this.running >= this.maxConcurrent) {
await new Promise(resolve => this.queue.push(resolve));
}
this.running++;
try {
return await request();
} finally {
this.running--;
if (this.queue.length > 0) {
this.queue.shift()();
}
}
}
}
6. 错误处理最佳实践
async function handleAsyncOperation() {
try {
const result = await someAsyncOperation();
return result;
} catch (error) {
// 错误分类处理
if (error instanceof NetworkError) {
// 处理网络错误
} else if (error instanceof ValidationError) {
// 处理验证错误
} else {
// 处理其他错误
}
throw error; // 重新抛出错误
}
}
7. 性能优化
// 缓存 Promise 结果
const memoizedPromise = (() => {
let cache = null;
return () => {
if (!cache) {
cache = new Promise((resolve) => {
// 执行耗时操作
setTimeout(() => resolve('result'), 1000);
});
}
return cache;
};
})();
8. 注意事项
8.1 避免 Promise 嵌套:
// 不好的写法
promise1().then(result1 => {
promise2().then(result2 => {
promise3().then(result3 => {
// ...
});
});
});
// 好的写法
promise1()
.then(result1 => promise2())
.then(result2 => promise3())
.then(result3 => {
// ...
});
8.2 始终添加错误处理:
somePromise()
.then(handleSuccess)
.catch(handleError)
.finally(cleanup);
8.3 合理使用 async/await:
// 更易读的异步代码
async function processData() {
try {
const data = await fetchData();
const processed = await processResult(data);
return processed;
} catch (error) {
handleError(error);
}
}