异步操作序列化
当有多个异步操作需要按顺序执行时,Promise 可以将它们串联起来,确保每个操作完成后下一个才开始。例如,先从服务器获取用户数据,再根据用户数据去获取其他相关信息:
function getUserData(userId) {
return new Promise((resolve, reject) => {
// 模拟异步获取用户数据
setTimeout(() => {
resolve({ id: userId, name: '张三' });
}, 1000);
});
}
function getRelatedInfo(userData) {
return new Promise((resolve, reject) => {
// 模拟根据用户数据获取其他信息
setTimeout(() => {
resolve({ userId: userData.id, info: '用户的相关信息' });
}, 1000);
});
}
getUserData(1)
.then(userData => {
console.log('获取到用户数据:', userData);
return getRelatedInfo(userData);
})
.then(relatedInfo => {
console.log('获取到相关用户信息:', relatedInfo);
});
并行执行多个异步操作
如果多个异步操作之间没有依赖关系,可以使用 Promise.all() 同时启动它们,等待所有操作完成后统一处理结果。例如,同时获取多个 API 的数据:
function getApi1Data() {
return new Promise(resolve => {
setTimeout(() => resolve('API1 的数据'), 1000);
});
}
function getApi2Data() {
return new Promise(resolve => {
setTimeout(() => resolve('API2 的数据'), 1500);
});
}
Promise.all([getApi1Data(), getApi2Data()])
.then(results => {
console.log('API1 数据:', results[0]);
console.log('API2 数据:', results[1]);
});
异步操作超时处理
在某些情况下,可能需要为异步操作设置超时时间,如果超过时间未完成则视为失败。Promise 可以结合 setTimeout 实现这一功能:
function fetchDataWithTimeout(url, timeout) {
return Promise.race([
fetch(url),
new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('请求超时'));
}, timeout);
})
]);
}
fetchDataWithTimeout('https://example.com/api/data', 3000)
.then(response => console.log('获取数据成功:', response))
.catch(error => console.error('获取数据失败:', error));
异步操作错误处理
Promise 提供了集中处理异步操作错误的机制,通过.catch() 方法可以捕获整个 Promise 链中的任何错误。例如:
function fetchData(url) {
return new Promise((resolve, reject) => {
// 模拟异步获取数据,可能出现错误
setTimeout(() => {
const data = { url: url, content: '数据内容' };
if (data.content) {
resolve(data);
} else {
reject(new Error('数据获取失败'));
}
}, 1000);
});
}
fetchData('https://example.com/api/data')
.then(data => {
console.log('获取数据成功:', data);
// 故意抛出错误,模拟后续处理出错
throw new Error('处理数据时出错');
})
.catch(error => {
console.error('发生错误:', error);
});
资源预加载
在 Web 开发中,常需要预加载图片、音频等资源,Promise 可以用于跟踪资源加载状态。例如:
function preloadImage(src) {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = () => reject(new Error(`图片加载失败: ${src}`));
img.src = src;
});
}
preloadImage('https://example.com/image.jpg')
.then(img => console.log('图片加载完成:', img))
.catch(error => console.error('图片加载错误:', error));
定时器操作
在需要延迟执行某些操作或创建定时器时,Promise 也可以发挥作用。例如,创建一个延迟一定时间后 resolve 的 Promise:
function delay(time) {
return new Promise(resolve => {
setTimeout(resolve, time);
});
}
delay(2000)
.then(() => {
console.log('延迟 2 秒后执行');
});