Search K
Appearance
Appearance
📊 SEO元描述:2024年最新JavaScript Promise静态方法教程,详解Promise.all并行处理、Promise.race竞争机制、Promise.allSettled全部完成、Promise.any任一成功。包含完整代码示例和并发控制策略。
核心关键词:JavaScript Promise静态方法2024、Promise.all并行处理、Promise.race竞争机制、Promise.allSettled、Promise.any、Promise并发控制
长尾关键词:Promise.all怎么用、Promise.race应用场景、Promise静态方法区别、JavaScript并发异步处理、Promise批量处理
通过本节JavaScript Promise静态方法详解,你将系统性掌握:
Promise静态方法是什么?这是Promise提供的强大工具集,用于处理多个异步操作的不同组合场景。Promise静态方法包括Promise.all()并行处理、Promise.race()竞争机制、Promise.allSettled()全部完成、Promise.any()任一成功等,是异步并发控制的核心工具。
💡 学习建议:理解Promise静态方法需要从实际应用场景出发,重点掌握每个方法的适用场景和行为特点。
// 🎉 Promise.all()详解
console.log("=== Promise.all()详解 ===");
// 基本的Promise.all用法
function basicPromiseAll() {
console.log("1. 基本Promise.all用法");
// 创建多个异步操作
const promise1 = new Promise(resolve => {
setTimeout(() => {
console.log("任务1完成");
resolve("结果1");
}, 1000);
});
const promise2 = new Promise(resolve => {
setTimeout(() => {
console.log("任务2完成");
resolve("结果2");
}, 1500);
});
const promise3 = new Promise(resolve => {
setTimeout(() => {
console.log("任务3完成");
resolve("结果3");
}, 800);
});
console.log("开始并行执行所有任务...");
const startTime = Date.now();
Promise.all([promise1, promise2, promise3])
.then(results => {
const endTime = Date.now();
console.log("所有任务完成,耗时:", endTime - startTime, "ms");
console.log("结果数组:", results);
console.log("结果顺序与输入顺序一致");
})
.catch(error => {
console.log("有任务失败:", error.message);
});
}
// Promise.all的失败处理
function promiseAllFailureHandling() {
console.log("\n2. Promise.all的失败处理");
const successPromise = new Promise(resolve => {
setTimeout(() => {
console.log("成功任务完成");
resolve("成功结果");
}, 1000);
});
const failurePromise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("失败任务执行");
reject(new Error("任务失败"));
}, 1500);
});
const anotherSuccessPromise = new Promise(resolve => {
setTimeout(() => {
console.log("另一个成功任务完成");
resolve("另一个成功结果");
}, 2000);
});
console.log("开始执行包含失败任务的Promise.all...");
Promise.all([successPromise, failurePromise, anotherSuccessPromise])
.then(results => {
console.log("这行不会执行,因为有任务失败");
})
.catch(error => {
console.log("Promise.all失败:", error.message);
console.log("注意:即使其他任务成功,整个Promise.all也会失败");
});
}
// Promise.all的实际应用场景
function promiseAllPracticalUsage() {
console.log("\n3. Promise.all的实际应用场景");
// 模拟获取用户完整信息的场景
function fetchUserProfile(userId) {
console.log(`开始获取用户${userId}的完整信息...`);
// 并行获取用户的不同信息
const userBasicInfo = fetch(`/api/users/${userId}/basic`);
const userPermissions = fetch(`/api/users/${userId}/permissions`);
const userPreferences = fetch(`/api/users/${userId}/preferences`);
const userStats = fetch(`/api/users/${userId}/stats`);
return Promise.all([
userBasicInfo,
userPermissions,
userPreferences,
userStats
]).then(responses => {
console.log("所有用户信息获取完成");
return {
basic: responses[0],
permissions: responses[1],
preferences: responses[2],
stats: responses[3],
timestamp: new Date().toISOString()
};
});
}
// 模拟fetch函数
function fetch(url) {
return new Promise(resolve => {
const delay = Math.random() * 1000 + 500;
setTimeout(() => {
resolve(`${url}的数据`);
}, delay);
});
}
fetchUserProfile(123)
.then(profile => {
console.log("用户完整信息:", profile);
})
.catch(error => {
console.log("获取用户信息失败:", error.message);
});
}
// Promise.all的性能优势演示
function promiseAllPerformanceDemo() {
console.log("\n4. Promise.all的性能优势演示");
// 串行执行
async function serialExecution() {
console.log("开始串行执行...");
const startTime = Date.now();
const result1 = await new Promise(resolve => {
setTimeout(() => resolve("串行结果1"), 1000);
});
const result2 = await new Promise(resolve => {
setTimeout(() => resolve("串行结果2"), 1000);
});
const result3 = await new Promise(resolve => {
setTimeout(() => resolve("串行结果3"), 1000);
});
const endTime = Date.now();
console.log("串行执行完成,耗时:", endTime - startTime, "ms");
return [result1, result2, result3];
}
// 并行执行
function parallelExecution() {
console.log("开始并行执行...");
const startTime = Date.now();
const promises = [
new Promise(resolve => setTimeout(() => resolve("并行结果1"), 1000)),
new Promise(resolve => setTimeout(() => resolve("并行结果2"), 1000)),
new Promise(resolve => setTimeout(() => resolve("并行结果3"), 1000))
];
return Promise.all(promises).then(results => {
const endTime = Date.now();
console.log("并行执行完成,耗时:", endTime - startTime, "ms");
return results;
});
}
// 执行对比
serialExecution().then(results => {
console.log("串行结果:", results);
return parallelExecution();
}).then(results => {
console.log("并行结果:", results);
console.log("性能提升明显:并行执行比串行执行快约2倍");
});
}
// 运行演示
basicPromiseAll();
promiseAllFailureHandling();
promiseAllPracticalUsage();
promiseAllPerformanceDemo();// 🎉 Promise.race()详解
console.log("=== Promise.race()详解 ===");
// 基本的Promise.race用法
function basicPromiseRace() {
console.log("1. 基本Promise.race用法");
const fastPromise = new Promise(resolve => {
setTimeout(() => {
console.log("快速任务完成");
resolve("快速结果");
}, 800);
});
const slowPromise = new Promise(resolve => {
setTimeout(() => {
console.log("慢速任务完成");
resolve("慢速结果");
}, 2000);
});
const mediumPromise = new Promise(resolve => {
setTimeout(() => {
console.log("中速任务完成");
resolve("中速结果");
}, 1200);
});
console.log("开始竞争执行...");
Promise.race([fastPromise, slowPromise, mediumPromise])
.then(result => {
console.log("最先完成的结果:", result);
console.log("注意:其他任务仍在后台继续执行");
});
}
// Promise.race的超时控制应用
function promiseRaceTimeout() {
console.log("\n2. Promise.race的超时控制应用");
// 创建超时Promise
function createTimeoutPromise(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error(`操作超时 (${ms}ms)`));
}, ms);
});
}
// 模拟可能很慢的网络请求
function slowNetworkRequest() {
return new Promise(resolve => {
const delay = Math.random() * 4000 + 1000; // 1-5秒随机延迟
setTimeout(() => {
resolve("网络请求成功");
}, delay);
});
}
// 带超时控制的请求
function requestWithTimeout(timeoutMs) {
console.log(`发起带${timeoutMs}ms超时的网络请求...`);
return Promise.race([
slowNetworkRequest(),
createTimeoutPromise(timeoutMs)
]);
}
// 测试不同的超时时间
requestWithTimeout(2000)
.then(result => {
console.log("请求成功:", result);
})
.catch(error => {
console.log("请求失败:", error.message);
});
setTimeout(() => {
requestWithTimeout(6000)
.then(result => {
console.log("长超时请求成功:", result);
})
.catch(error => {
console.log("长超时请求失败:", error.message);
});
}, 1000);
}
// Promise.race的实际应用:多数据源竞争
function promiseRaceMultipleDataSources() {
console.log("\n3. Promise.race多数据源竞争");
// 模拟多个数据源
function fetchFromPrimaryServer() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.3) {
resolve("主服务器数据");
} else {
reject(new Error("主服务器故障"));
}
}, Math.random() * 2000 + 500);
});
}
function fetchFromBackupServer() {
return new Promise(resolve => {
setTimeout(() => {
resolve("备份服务器数据");
}, Math.random() * 3000 + 1000);
});
}
function fetchFromCDN() {
return new Promise(resolve => {
setTimeout(() => {
resolve("CDN数据");
}, Math.random() * 1500 + 300);
});
}
// 从多个数据源竞争获取数据
function fetchDataFromMultipleSources() {
console.log("从多个数据源竞争获取数据...");
return Promise.race([
fetchFromPrimaryServer().catch(error => {
console.log("主服务器失败:", error.message);
throw error;
}),
fetchFromBackupServer(),
fetchFromCDN()
]);
}
fetchDataFromMultipleSources()
.then(result => {
console.log("最快获取到的数据:", result);
})
.catch(error => {
console.log("所有数据源都失败了:", error.message);
});
}
// 运行演示
basicPromiseRace();
promiseRaceTimeout();
promiseRaceMultipleDataSources();// 🎉 Promise.allSettled()详解
console.log("=== Promise.allSettled()详解 ===");
// 基本的Promise.allSettled用法
function basicPromiseAllSettled() {
console.log("1. 基本Promise.allSettled用法");
const promises = [
Promise.resolve("成功1"),
Promise.reject(new Error("失败1")),
Promise.resolve("成功2"),
new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() > 0.5) {
resolve("随机成功");
} else {
reject(new Error("随机失败"));
}
}, 1000);
})
];
console.log("开始执行Promise.allSettled...");
Promise.allSettled(promises)
.then(results => {
console.log("所有Promise都已settled:");
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
console.log(`Promise ${index}: 成功 - ${result.value}`);
} else {
console.log(`Promise ${index}: 失败 - ${result.reason.message}`);
}
});
// 统计成功和失败的数量
const successful = results.filter(r => r.status === 'fulfilled');
const failed = results.filter(r => r.status === 'rejected');
console.log(`成功: ${successful.length}, 失败: ${failed.length}`);
});
}
// Promise.allSettled vs Promise.all对比
function allSettledVsAll() {
console.log("\n2. Promise.allSettled vs Promise.all对比");
const mixedPromises = [
Promise.resolve("成功任务1"),
Promise.reject(new Error("失败任务")),
Promise.resolve("成功任务2")
];
console.log("使用Promise.all:");
Promise.all(mixedPromises)
.then(results => {
console.log("Promise.all成功:", results);
})
.catch(error => {
console.log("Promise.all失败:", error.message);
console.log("无法获取成功任务的结果");
});
console.log("使用Promise.allSettled:");
Promise.allSettled(mixedPromises)
.then(results => {
console.log("Promise.allSettled完成:");
const successResults = results
.filter(r => r.status === 'fulfilled')
.map(r => r.value);
const errorResults = results
.filter(r => r.status === 'rejected')
.map(r => r.reason.message);
console.log("成功的结果:", successResults);
console.log("失败的错误:", errorResults);
});
}
// Promise.allSettled的实际应用:批量操作
function allSettledBatchOperations() {
console.log("\n3. Promise.allSettled批量操作应用");
// 模拟批量文件上传
function uploadFile(filename) {
return new Promise((resolve, reject) => {
const uploadTime = Math.random() * 2000 + 500;
setTimeout(() => {
// 模拟30%的失败率
if (Math.random() < 0.7) {
resolve({
filename,
url: `https://cdn.example.com/${filename}`,
size: Math.floor(Math.random() * 1000000),
uploadTime: uploadTime
});
} else {
reject(new Error(`上传失败: ${filename}`));
}
}, uploadTime);
});
}
// 批量上传文件
function batchUploadFiles(filenames) {
console.log("开始批量上传文件:", filenames);
const uploadPromises = filenames.map(filename => uploadFile(filename));
return Promise.allSettled(uploadPromises)
.then(results => {
const successful = [];
const failed = [];
results.forEach((result, index) => {
if (result.status === 'fulfilled') {
successful.push(result.value);
} else {
failed.push({
filename: filenames[index],
error: result.reason.message
});
}
});
return {
successful,
failed,
total: filenames.length,
successRate: (successful.length / filenames.length * 100).toFixed(1)
};
});
}
const files = ["doc1.pdf", "image1.jpg", "data.csv", "report.xlsx", "backup.zip"];
batchUploadFiles(files)
.then(result => {
console.log("批量上传完成:");
console.log(`成功率: ${result.successRate}% (${result.successful.length}/${result.total})`);
console.log("成功上传:", result.successful.map(f => f.filename));
console.log("失败文件:", result.failed.map(f => f.filename));
});
}
// 运行演示
basicPromiseAllSettled();
allSettledVsAll();
allSettledBatchOperations();// 🎉 Promise.any()和其他静态方法
console.log("=== Promise.any()和其他静态方法 ===");
// Promise.any()基本用法
function basicPromiseAny() {
console.log("1. Promise.any()基本用法");
const promises = [
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("第一个失败")), 1000);
}),
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error("第二个失败")), 1500);
}),
new Promise(resolve => {
setTimeout(() => resolve("第三个成功"), 800);
}),
new Promise(resolve => {
setTimeout(() => resolve("第四个成功"), 1200);
})
];
console.log("开始执行Promise.any...");
Promise.any(promises)
.then(result => {
console.log("Promise.any成功,第一个成功的结果:", result);
})
.catch(error => {
console.log("Promise.any失败,所有Promise都失败了");
console.log("AggregateError:", error.errors.map(e => e.message));
});
}
// Promise.resolve()和Promise.reject()
function promiseResolveReject() {
console.log("\n2. Promise.resolve()和Promise.reject()");
// Promise.resolve()的不同用法
console.log("Promise.resolve()用法:");
// 直接resolve一个值
Promise.resolve("直接值").then(value => {
console.log("直接值:", value);
});
// resolve一个Promise
const existingPromise = new Promise(resolve => {
setTimeout(() => resolve("现有Promise的值"), 500);
});
Promise.resolve(existingPromise).then(value => {
console.log("现有Promise:", value);
});
// resolve一个thenable对象
const thenable = {
then(resolve, reject) {
setTimeout(() => resolve("thenable对象的值"), 300);
}
};
Promise.resolve(thenable).then(value => {
console.log("thenable对象:", value);
});
// Promise.reject()用法
console.log("Promise.reject()用法:");
Promise.reject(new Error("直接错误"))
.catch(error => {
console.log("捕获直接错误:", error.message);
});
Promise.reject("字符串错误")
.catch(error => {
console.log("捕获字符串错误:", error);
});
}
// 静态方法的组合使用
function staticMethodsCombination() {
console.log("\n3. 静态方法的组合使用");
// 模拟复杂的数据获取场景
function fetchUserData(userId) {
// 必须成功的核心数据
const coreDataPromises = [
fetchUserProfile(userId),
fetchUserPermissions(userId)
];
// 可选的附加数据
const optionalDataPromises = [
fetchUserPreferences(userId),
fetchUserStats(userId),
fetchUserActivity(userId)
];
// 备用数据源
const backupDataPromises = [
fetchFromBackupServer(userId),
fetchFromCache(userId)
];
console.log("开始复杂的数据获取流程...");
return Promise.all([
// 核心数据必须全部成功
Promise.all(coreDataPromises),
// 可选数据允许部分失败
Promise.allSettled(optionalDataPromises),
// 备用数据只需要一个成功
Promise.any(backupDataPromises).catch(() => null)
]).then(([coreData, optionalData, backupData]) => {
const [profile, permissions] = coreData;
const optionalResults = {};
optionalData.forEach((result, index) => {
const keys = ['preferences', 'stats', 'activity'];
if (result.status === 'fulfilled') {
optionalResults[keys[index]] = result.value;
}
});
return {
core: { profile, permissions },
optional: optionalResults,
backup: backupData,
timestamp: new Date().toISOString()
};
});
}
// 模拟各种数据获取函数
function fetchUserProfile(userId) {
return Promise.resolve({ id: userId, name: `用户${userId}` });
}
function fetchUserPermissions(userId) {
return Promise.resolve(['read', 'write']);
}
function fetchUserPreferences(userId) {
return Math.random() > 0.3
? Promise.resolve({ theme: 'dark' })
: Promise.reject(new Error('偏好设置获取失败'));
}
function fetchUserStats(userId) {
return Math.random() > 0.4
? Promise.resolve({ loginCount: 42 })
: Promise.reject(new Error('统计数据获取失败'));
}
function fetchUserActivity(userId) {
return Math.random() > 0.5
? Promise.resolve({ lastActive: new Date() })
: Promise.reject(new Error('活动数据获取失败'));
}
function fetchFromBackupServer(userId) {
return new Promise((resolve, reject) => {
setTimeout(() => {
Math.random() > 0.6
? resolve('备份服务器数据')
: reject(new Error('备份服务器失败'));
}, 1000);
});
}
function fetchFromCache(userId) {
return new Promise(resolve => {
setTimeout(() => resolve('缓存数据'), 200);
});
}
fetchUserData(123)
.then(result => {
console.log("复杂数据获取完成:", result);
})
.catch(error => {
console.log("核心数据获取失败:", error.message);
});
}
// 运行演示
basicPromiseAny();
promiseResolveReject();
staticMethodsCombination();通过本节JavaScript Promise静态方法详解的学习,你已经掌握:
A: 当需要所有操作都成功时使用Promise.all;当允许部分操作失败,需要获取所有结果时使用Promise.allSettled。
A: 主要用于超时控制、多数据源竞争、用户体验优化(如显示最快加载的内容)等场景。
A: Promise.race返回第一个settled的Promise结果(成功或失败),Promise.any返回第一个成功的Promise结果,只有全部失败才reject。
A: 可以使用分批处理、信号量控制、或者第三方库如p-limit来控制Promise的并发执行数量。
A: Promise静态方法本身性能很好,主要的性能考虑在于合理控制并发数量,避免同时发起过多的异步操作。
"掌握Promise静态方法是构建高效异步应用的关键技能。通过本节的学习,你已经能够灵活运用各种Promise静态方法来处理复杂的异步场景。接下来学习Promise高级应用,你将掌握更深入的Promise使用技巧和最佳实践!"