Promise的详细讲解
一、基本概念
、
Promise 是 JavaScript 中的一种对象,用于异步计算。它代表一个现在、将来某个时间点或者永远不执行的值。
返回错误的状态。三种状态:
- Promise 有以下Pending(进行中):初始状态,既不是成功,也不是失败。
- Fulfilled(已成功):操作成功完成,Promise 返回结果的状态。
- Rejected(已失败):操作失败,Promise
二、创建 Promise
通过 new Promise() 创建一个 Promise 对象,并传入一个执行器函数,该函数接收两个参数:resolve 和 reject,分别用于将 Promise 状态改为成功或失败。
const myPromise = new Promise((resolve, reject) => {// 异步操作模拟setTimeout(() => {const isSuccess = true;if (isSuccess) {resolve("操作成功!"); // 成功} else {reject("操作失败!"); // 失败}}, 1000);
});myPromise.then((value) => {console.log(value); // "操作成功!"}).catch((error) => {console.error(error); // "操作失败!"});
这是一个对Promise的最基本使用
三、Promise 的方法
- .then()
- 用于处理 Promise 成功的情况。
- 可以链式调用,返回一个新的 Promise 对象。
- 参数是一个函数,该函数在 Promise 成功时调用,并接收成功的结果。
promise.then((result) => {// 处理成功的结果
});
- .catch()
- 用于处理 Promise 失败的情况。
- 参数是一个函数,该函数在 Promise 失败时调用,并接收错误信息。
promise.catch((error) => {// 处理错误
});
- .finally()
- 无论 Promise 成功还是失败,都会执行。
- 通常用于清理工作,如关闭加载指示器等。
promise.then((result) => {// 处理成功}).catch((error) => {// 处理失败}).finally(() => {// 无论成功还是失败都会执行});
四、Promise 的静态方法
- Promise.all()
- 接收一个 Promise 对象的可迭代对象(如数组)。
- 返回一个新的 Promise,只有当所有传入的 Promise 都成功时才会成功,否则只要有一个失败就会失败。
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = Promise.reject(3);Promise.all([promise1, promise2, promise3]).then((results) => {console.log(results); // 不会执行,因为 promise3 失败}).catch((error) => {console.error(error); // 3});
- Promise.race()
- 接收一个 Promise 对象的可迭代对象。
- 返回一个新的 Promise,只要有一个 Promise 成功或失败,就会立即采用该 Promise 的结果。
const promise1 = new Promise((resolve) => setTimeout(resolve, 1000, "1"));
const promise2 = new Promise((resolve) => setTimeout(resolve, 500, "2"));Promise.race([promise1, promise2]).then((result) => {console.log(result); // "2",因为 promise2 更快完成
});
- Promise.resolve()
- 将参数转化为 Promise 对象。
- 如果参数已经是 Promise,则直接返回;否则返回一个新的成功 Promise。
const promise = Promise.resolve(123);
promise.then((value) => console.log(value)); // 123
- Promise.reject()
- 返回一个新的失败的 Promise 对象,失败原因由参数指定。
const promise = Promise.reject("失败原因");
promise.catch((error) => console.error(error)); // "失败原因"
五、实际应用场景
- 并行请求数据
const fetchUserData = () => {return new Promise((resolve) => {setTimeout(() => resolve({ id: 1, name: "John" }), 1000);});
};const fetchPosts = () => {return new Promise((resolve) => {setTimeout(() => resolve([{ id: 1, title: "Post 1" }]), 1500);});
};Promise.all([fetchUserData(), fetchPosts()]).then(([user, posts]) => {console.log("User:", user);console.log("Posts:", posts);}).catch((error) => {console.error("Error:", error);});
- 串行执行异步操作
const task1 = () => {return new Promise((resolve) => {setTimeout(() => resolve("任务1完成"), 1000);});
};const task2 = (message) => {return new Promise((resolve) => {setTimeout(() => resolve(`${message}, 任务2完成`), 1000);});
};task1().then((result) => {console.log(result); // "任务1完成"return task2(result);}).then((result) => {console.log(result); // "任务1完成, 任务2完成"});
六、错误处理
- 在 .then() 中处理错误:可以在 .then() 的第二个参数中传入一个错误处理函数,但不推荐这种方式。
promise.then((result) => {// 处理成功},(error) => {// 处理错误}
);
- 使用 .catch() 处理错误:推荐使用 .catch() 来处理错误,因为它可以捕获前面所有 .then() 中抛出的错误。
promise.then((result) => {// 处理成功throw new Error("出错了!");}).catch((error) => {// 处理错误console.error(error.message); // "出错了!"});
七、Promise 的优势
- 更好的错误处理:与传统的回调函数相比,Promise 提供了更统一的错误处理机制。
- 避免回调地狱:通过链式调用 .then(),可以避免嵌套过多的回调函数。
- 更清晰的代码结构:Promise 使异步代码更易于阅读和维护。
八、Promise 的缺点
- 无法取消:一旦 Promise 创建,就无法取消其执行,即使你可能不再需要结果。
- 错误传播有限:如果在 .then() 中忘记返回 Promise,错误可能无法正确传播到 .catch()。
九、ES2017 的 async/await
async/await 是基于 Promise 的语法糖,使异步代码看起来更像同步代码。
- async 函数