Search K
Appearance
Appearance
📊 SEO元描述:2024年最新JavaScript Promise基本用法教程,详解then方法链式调用、catch错误捕获、finally无条件执行。包含完整代码示例和最佳实践,适合前端开发者掌握Promise异步编程。
核心关键词:JavaScript Promise用法2024、Promise then方法、Promise catch错误处理、Promise链式调用、Promise finally方法
长尾关键词:Promise怎么使用、Promise then catch finally、Promise链式调用详解、Promise错误处理最佳实践、JavaScript异步编程Promise
通过本节JavaScript Promise基本用法详解,你将系统性掌握:
**Promise的基本用法是什么?**这是将Promise理论转化为实践的关键问题。Promise提供了三个核心方法:then()处理成功、catch()处理失败、finally()无条件执行,这些方法构成了Promise异步编程的完整体系。
💡 学习建议:理解Promise的基本用法需要通过大量实践来掌握,重点关注方法的返回值和链式调用的机制。
// 🎉 then方法详解
console.log("=== Promise then方法详解 ===");
// 基本的then用法
function basicThenUsage() {
console.log("1. 基本then用法");
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.3;
if (success) {
resolve({
id: 1,
message: "操作成功",
timestamp: new Date().toISOString()
});
} else {
reject(new Error("操作失败"));
}
}, 1000);
});
// then方法接收一个或两个参数
promise.then(
// 第一个参数:成功回调
(value) => {
console.log("✅ Promise成功:", value);
return value; // 返回值会传递给下一个then
},
// 第二个参数:失败回调(可选,通常用catch代替)
(error) => {
console.log("❌ Promise失败:", error.message);
throw error; // 重新抛出错误
}
);
return promise;
}
// then方法的返回值处理
function thenReturnValues() {
console.log("\n2. then方法返回值处理");
// 返回普通值
Promise.resolve("初始值")
.then(value => {
console.log("接收到:", value);
return "转换后的值"; // 返回普通值
})
.then(value => {
console.log("转换结果:", value);
});
// 返回Promise
Promise.resolve("开始")
.then(value => {
console.log("第一步:", value);
// 返回一个新的Promise
return new Promise(resolve => {
setTimeout(() => {
resolve("异步处理结果");
}, 500);
});
})
.then(value => {
console.log("异步结果:", value);
});
// 返回undefined
Promise.resolve("有值")
.then(value => {
console.log("处理:", value);
// 没有return语句,相当于return undefined
})
.then(value => {
console.log("下一步接收到:", value); // undefined
});
}
// then方法的链式调用
function thenChaining() {
console.log("\n3. then方法链式调用");
// 数据处理管道
Promise.resolve([1, 2, 3, 4, 5])
.then(numbers => {
console.log("原始数组:", numbers);
return numbers.map(n => n * 2); // 每个数乘以2
})
.then(doubled => {
console.log("乘以2后:", doubled);
return doubled.filter(n => n > 5); // 过滤大于5的数
})
.then(filtered => {
console.log("过滤后:", filtered);
return filtered.reduce((sum, n) => sum + n, 0); // 求和
})
.then(sum => {
console.log("最终结果:", sum);
})
.catch(error => {
console.error("处理过程中出错:", error);
});
}
// 运行演示
basicThenUsage();
thenReturnValues();
thenChaining();// 🎉 catch方法详解
console.log("=== Promise catch方法详解 ===");
// 基本的catch用法
function basicCatchUsage() {
console.log("1. 基本catch用法");
// 创建一个会失败的Promise
const failingPromise = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("网络连接失败"));
}, 1000);
});
failingPromise
.then(value => {
console.log("这行不会执行");
})
.catch(error => {
console.log("捕获到错误:", error.message);
// 可以在catch中进行错误处理
if (error.message.includes("网络")) {
console.log("这是网络错误,建议检查网络连接");
}
});
}
// catch捕获不同类型的错误
function catchDifferentErrors() {
console.log("\n2. catch捕获不同类型的错误");
// Promise构造函数中的错误
const constructorError = new Promise((resolve, reject) => {
throw new Error("构造函数中的错误");
});
constructorError.catch(error => {
console.log("捕获构造函数错误:", error.message);
});
// then方法中的错误
Promise.resolve("正常值")
.then(value => {
console.log("处理值:", value);
throw new Error("then方法中的错误");
})
.catch(error => {
console.log("捕获then方法错误:", error.message);
});
// 异步操作中的错误
Promise.resolve("开始异步操作")
.then(value => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("异步操作失败"));
}, 500);
});
})
.catch(error => {
console.log("捕获异步操作错误:", error.message);
});
}
// catch的错误传播
function catchErrorPropagation() {
console.log("\n3. catch的错误传播");
Promise.resolve("开始")
.then(value => {
console.log("步骤1:", value);
return "步骤1完成";
})
.then(value => {
console.log("步骤2:", value);
throw new Error("步骤2失败");
})
.then(value => {
console.log("步骤3: 这行不会执行");
return "步骤3完成";
})
.then(value => {
console.log("步骤4: 这行也不会执行");
})
.catch(error => {
console.log("错误被捕获:", error.message);
return "错误已处理"; // 返回值,继续链式调用
})
.then(value => {
console.log("错误处理后继续:", value);
});
}
// catch的错误恢复
function catchErrorRecovery() {
console.log("\n4. catch的错误恢复");
// 模拟网络请求失败后的重试机制
function fetchDataWithRetry(url, maxRetries = 3) {
let attempts = 0;
function attemptFetch() {
attempts++;
console.log(`尝试获取数据,第${attempts}次`);
return new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟70%的失败率
if (Math.random() < 0.7) {
reject(new Error(`网络请求失败 (尝试${attempts})`));
} else {
resolve(`数据获取成功 (尝试${attempts})`);
}
}, 300);
});
}
return attemptFetch()
.catch(error => {
console.log("请求失败:", error.message);
if (attempts < maxRetries) {
console.log(`准备重试,剩余${maxRetries - attempts}次机会`);
return attemptFetch();
} else {
throw new Error(`所有重试都失败了,共尝试${attempts}次`);
}
});
}
fetchDataWithRetry("https://api.example.com/data")
.then(result => {
console.log("最终成功:", result);
})
.catch(error => {
console.log("最终失败:", error.message);
});
}
// 运行演示
basicCatchUsage();
catchDifferentErrors();
catchErrorPropagation();
catchErrorRecovery();// 🎉 finally方法详解
console.log("=== Promise finally方法详解 ===");
// 基本的finally用法
function basicFinallyUsage() {
console.log("1. 基本finally用法");
function performOperation(shouldSucceed) {
console.log(`开始操作 (成功概率: ${shouldSucceed ? '高' : '低'})`);
return new Promise((resolve, reject) => {
setTimeout(() => {
if (shouldSucceed) {
resolve("操作成功");
} else {
reject(new Error("操作失败"));
}
}, 1000);
})
.then(result => {
console.log("✅ 成功:", result);
return result;
})
.catch(error => {
console.log("❌ 失败:", error.message);
throw error;
})
.finally(() => {
console.log("🔄 清理工作:无论成功失败都会执行");
console.log("🔄 关闭连接、清理资源等");
});
}
// 测试成功情况
performOperation(true);
// 测试失败情况
setTimeout(() => {
performOperation(false);
}, 2000);
}
// finally的实际应用场景
function finallyPracticalUsage() {
console.log("\n2. finally的实际应用场景");
// 模拟文件操作
class FileManager {
constructor() {
this.openFiles = new Set();
}
processFile(filename) {
console.log(`开始处理文件: ${filename}`);
// 打开文件
this.openFiles.add(filename);
console.log(`文件已打开: ${filename}`);
return new Promise((resolve, reject) => {
setTimeout(() => {
// 模拟文件处理
if (filename.includes("error")) {
reject(new Error(`文件处理失败: ${filename}`));
} else {
resolve(`文件处理成功: ${filename}`);
}
}, 1000);
})
.then(result => {
console.log("✅", result);
return result;
})
.catch(error => {
console.log("❌", error.message);
throw error;
})
.finally(() => {
// 无论成功失败都要关闭文件
this.openFiles.delete(filename);
console.log(`🔒 文件已关闭: ${filename}`);
console.log(`📊 当前打开的文件数: ${this.openFiles.size}`);
});
}
getOpenFilesCount() {
return this.openFiles.size;
}
}
const fileManager = new FileManager();
// 处理多个文件
const files = ["data.txt", "config.json", "error.log"];
files.forEach((filename, index) => {
setTimeout(() => {
fileManager.processFile(filename)
.then(result => {
console.log(`处理完成: ${result}`);
})
.catch(error => {
console.log(`处理失败: ${error.message}`);
});
}, index * 1500);
});
}
// finally与return值
function finallyReturnValue() {
console.log("\n3. finally与return值");
// finally不会改变Promise的值
Promise.resolve("原始值")
.finally(() => {
console.log("finally执行");
return "finally的返回值"; // 这个返回值会被忽略
})
.then(value => {
console.log("最终接收到的值:", value); // 仍然是"原始值"
});
// finally中抛出错误会改变Promise状态
Promise.resolve("成功值")
.finally(() => {
console.log("finally中抛出错误");
throw new Error("finally中的错误");
})
.then(value => {
console.log("这行不会执行");
})
.catch(error => {
console.log("捕获finally中的错误:", error.message);
});
// finally中返回rejected Promise
Promise.resolve("成功值")
.finally(() => {
console.log("finally中返回rejected Promise");
return Promise.reject(new Error("finally中的rejected Promise"));
})
.then(value => {
console.log("这行不会执行");
})
.catch(error => {
console.log("捕获finally中的rejected Promise:", error.message);
});
}
// 运行演示
basicFinallyUsage();
finallyPracticalUsage();
finallyReturnValue();// 🎉 Promise链式调用深入理解
console.log("=== Promise链式调用深入理解 ===");
// 链式调用的基本原理
function chainingPrinciples() {
console.log("1. 链式调用的基本原理");
// 每个then/catch/finally都返回一个新的Promise
const promise1 = Promise.resolve("初始值");
console.log("promise1:", promise1);
const promise2 = promise1.then(value => {
console.log("第一个then接收:", value);
return "第一个then返回";
});
console.log("promise2:", promise2);
console.log("promise1 === promise2:", promise1 === promise2); // false
const promise3 = promise2.then(value => {
console.log("第二个then接收:", value);
return "第二个then返回";
});
console.log("promise3:", promise3);
console.log("promise2 === promise3:", promise2 === promise3); // false
promise3.then(value => {
console.log("最终值:", value);
});
}
// 复杂的链式调用示例
function complexChaining() {
console.log("\n2. 复杂的链式调用示例");
// 模拟用户注册流程
function registerUser(userData) {
console.log("开始用户注册流程...");
return Promise.resolve(userData)
.then(data => {
console.log("步骤1: 验证用户数据");
if (!data.email || !data.password) {
throw new Error("邮箱和密码不能为空");
}
return { ...data, validated: true };
})
.then(data => {
console.log("步骤2: 检查邮箱是否已存在");
return new Promise(resolve => {
setTimeout(() => {
const exists = data.email === "existing@example.com";
if (exists) {
throw new Error("邮箱已存在");
}
resolve({ ...data, emailChecked: true });
}, 500);
});
})
.then(data => {
console.log("步骤3: 加密密码");
return new Promise(resolve => {
setTimeout(() => {
resolve({
...data,
password: `encrypted_${data.password}`,
encrypted: true
});
}, 300);
});
})
.then(data => {
console.log("步骤4: 保存到数据库");
return new Promise(resolve => {
setTimeout(() => {
resolve({
id: Math.floor(Math.random() * 1000),
email: data.email,
createdAt: new Date().toISOString(),
status: "active"
});
}, 400);
});
})
.then(user => {
console.log("步骤5: 发送欢迎邮件");
return new Promise(resolve => {
setTimeout(() => {
console.log(`欢迎邮件已发送到: ${user.email}`);
resolve({ ...user, welcomeEmailSent: true });
}, 200);
});
})
.catch(error => {
console.error("注册失败:", error.message);
// 根据错误类型进行不同处理
if (error.message.includes("邮箱已存在")) {
return { error: "EMAIL_EXISTS", message: "该邮箱已被注册" };
} else if (error.message.includes("不能为空")) {
return { error: "VALIDATION_ERROR", message: "请填写完整信息" };
} else {
return { error: "UNKNOWN_ERROR", message: "注册过程中发生未知错误" };
}
})
.finally(() => {
console.log("注册流程结束,清理临时资源");
});
}
// 测试成功注册
registerUser({
email: "newuser@example.com",
password: "password123",
name: "新用户"
}).then(result => {
console.log("注册结果:", result);
});
// 测试失败注册
setTimeout(() => {
registerUser({
email: "existing@example.com",
password: "password123",
name: "已存在用户"
}).then(result => {
console.log("注册结果:", result);
});
}, 3000);
}
// 链式调用中的值传递
function chainingValuePassing() {
console.log("\n3. 链式调用中的值传递");
// 值的传递和转换
Promise.resolve(10)
.then(value => {
console.log(`接收到数字: ${value}`);
return value * 2; // 返回数字
})
.then(value => {
console.log(`数字乘以2: ${value}`);
return `字符串: ${value}`; // 返回字符串
})
.then(value => {
console.log(`接收到字符串: ${value}`);
return { number: 20, string: value }; // 返回对象
})
.then(value => {
console.log(`接收到对象:`, value);
return [value.number, value.string]; // 返回数组
})
.then(value => {
console.log(`接收到数组:`, value);
// 返回Promise
return new Promise(resolve => {
setTimeout(() => {
resolve(`异步处理结果: ${value.join(', ')}`);
}, 500);
});
})
.then(value => {
console.log(`最终结果: ${value}`);
});
}
// 运行演示
chainingPrinciples();
complexChaining();
chainingValuePassing();// 🎉 Promise错误传播和处理策略
console.log("=== Promise错误传播和处理策略 ===");
// 错误传播机制
function errorPropagation() {
console.log("1. 错误传播机制");
Promise.resolve("开始")
.then(value => {
console.log("步骤1:", value);
return "步骤1完成";
})
.then(value => {
console.log("步骤2:", value);
throw new Error("步骤2出错");
})
.then(value => {
console.log("步骤3: 不会执行");
return "步骤3完成";
})
.then(value => {
console.log("步骤4: 也不会执行");
return "步骤4完成";
})
.catch(error => {
console.log("错误被捕获:", error.message);
return "错误已处理"; // 恢复正常流程
})
.then(value => {
console.log("恢复后的步骤:", value);
});
}
// 多点错误处理
function multipleErrorHandling() {
console.log("\n2. 多点错误处理");
Promise.resolve("开始")
.then(value => {
console.log("步骤1:", value);
if (Math.random() < 0.5) {
throw new Error("步骤1随机错误");
}
return "步骤1完成";
})
.catch(error => {
console.log("捕获步骤1错误:", error.message);
return "步骤1错误已处理";
})
.then(value => {
console.log("步骤2:", value);
if (Math.random() < 0.5) {
throw new Error("步骤2随机错误");
}
return "步骤2完成";
})
.catch(error => {
console.log("捕获步骤2错误:", error.message);
return "步骤2错误已处理";
})
.then(value => {
console.log("最终结果:", value);
});
}
// 错误分类处理
function categorizedErrorHandling() {
console.log("\n3. 错误分类处理");
function processData(data) {
return Promise.resolve(data)
.then(data => {
// 验证数据
if (!data) {
const error = new Error("数据不能为空");
error.type = "VALIDATION_ERROR";
throw error;
}
return data;
})
.then(data => {
// 网络请求
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.3) {
const error = new Error("网络连接失败");
error.type = "NETWORK_ERROR";
reject(error);
} else {
resolve(`处理后的${data}`);
}
}, 500);
});
})
.then(result => {
// 业务逻辑处理
if (result.includes("error")) {
const error = new Error("业务逻辑错误");
error.type = "BUSINESS_ERROR";
throw error;
}
return result;
})
.catch(error => {
console.log(`捕获到${error.type}:`, error.message);
// 根据错误类型进行不同处理
switch (error.type) {
case "VALIDATION_ERROR":
return { error: true, message: "请检查输入数据", retry: false };
case "NETWORK_ERROR":
return { error: true, message: "网络错误,请稍后重试", retry: true };
case "BUSINESS_ERROR":
return { error: true, message: "业务处理失败", retry: false };
default:
return { error: true, message: "未知错误", retry: false };
}
});
}
// 测试不同类型的错误
processData(null).then(result => console.log("结果1:", result));
processData("normal data").then(result => console.log("结果2:", result));
processData("error data").then(result => console.log("结果3:", result));
}
// 运行演示
errorPropagation();
multipleErrorHandling();
categorizedErrorHandling();通过本节JavaScript Promise基本用法详解的学习,你已经掌握:
A: then的第二个参数只能捕获当前Promise的错误,而catch可以捕获整个Promise链中的错误。推荐使用catch方法进行错误处理。
A: 通常不会。finally中的返回值会被忽略,除非返回的是rejected Promise或抛出错误,这时会改变Promise链的状态。
A: 可以返回对象或数组来传递多个值,或者使用Promise.all来并行处理多个Promise并获取所有结果。
A: 错误会沿着Promise链向下传播,直到遇到catch方法或then方法的第二个参数。一旦错误被处理,链会恢复正常状态。
A: 可以将复杂的Promise链拆分为多个函数,使用async/await语法,或者合理使用Promise的静态方法来简化代码结构。
"掌握Promise的基本用法是现代JavaScript异步编程的核心技能。通过本节的学习,你已经能够熟练使用then、catch、finally方法构建复杂的异步流程。接下来学习Promise的静态方法,你将掌握更强大的异步操作组合和控制能力!"