Promise异步编程
Promise 是 JavaScript 中用于处理异步操作的一种机制,它解决了传统回调函数嵌套(回调地狱):回调地狱(Callback Hell) 是指在 JavaScript 中,由于多个异步操作嵌套使用回调函数,导致代码结构变得复杂、难以阅读和维护的现象。这种现象通常发生在处理多个依赖关系的异步任务时。的问题,使异步代码更易于编写和维护。以下是关于 Promise 的详细讲解:
1. 什么是 Promise?
- Promise 是一个对象,表示一个异步操作的最终完成(或失败)及其结果值。
- 它有三种状态:
- Pending(进行中):初始状态,既不是成功,也不是失败。
- Fulfilled(已成功):操作成功完成。
- Rejected(已失败):操作失败。
2. 创建 Promise
- 使用
new Promise()
构造函数创建 Promise 对象。 - 构造函数接受一个函数(通常称为执行器函数),该函数有两个参数:
resolve
和reject
。
const promise = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
const success = true;
if (success) {
resolve("Operation succeeded!"); // 成功时调用 resolve
} else {
reject("Operation failed!"); // 失败时调用 reject
}
}, 1000);
});
3. 使用 Promise
- 通过
.then()
处理成功的结果,通过.catch()
处理失败的结果。 - 还可以使用
.finally()
在 Promise 完成后执行清理操作(无论成功或失败)。
promise
.then((result) => {
console.log(result); // Operation succeeded!
})
.catch((error) => {
console.error(error); // Operation failed!
})
.finally(() => {
console.log("Promise completed!"); // 无论成功或失败都会执行
});
4. Promise 链式调用
.then()
方法返回一个新的 Promise,因此可以链式调用多个.then()
。- 每个
.then()
可以处理前一个 Promise 的结果。
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(10);
}, 1000);
});
};
fetchData()
.then((data) => {
console.log(data); // 10
return data * 2; // 返回新值
})
.then((data) => {
console.log(data); // 20
return data + 5; // 返回新值
})
.then((data) => {
console.log(data); // 25
})
.catch((error) => {
console.error(error);
});
5. Promise 的静态方法
Promise.resolve()
和 Promise.reject()
- 快速创建一个已成功或已失败的 Promise。
const resolvedPromise = Promise.resolve("Success!");
const rejectedPromise = Promise.reject("Error!");
Promise.all()
- 接收一个 Promise 数组,当所有 Promise 都成功时返回结果数组;如果有一个失败,则立即返回失败。
const promise1 = Promise.resolve(1);
const promise2 = Promise.resolve(2);
const promise3 = new Promise((resolve) => setTimeout(resolve, 1000, 3));
Promise.all([promise1, promise2, promise3])
.then((results) => {
console.log(results); // [1, 2, 3]
})
.catch((error) => {
console.error(error);
});
Promise.race()
- 接收一个 Promise 数组,返回第一个完成(无论成功或失败)的 Promise 的结果。
const promise1 = new Promise((resolve) => setTimeout(resolve, 500, "First"));
const promise2 = new Promise((resolve) => setTimeout(resolve, 1000, "Second"));
Promise.race([promise1, promise2])
.then((result) => {
console.log(result); // First
})
.catch((error) => {
console.error(error);
});
Promise.allSettled()
- 接收一个 Promise 数组,等待所有 Promise 完成(无论成功或失败),返回结果数组。
const promise1 = Promise.resolve(1);
const promise2 = Promise.reject("Error!");
Promise.allSettled([promise1, promise2])
.then((results) => {
console.log(results);
// [
// { status: 'fulfilled', value: 1 },
// { status: 'rejected', reason: 'Error!' }
// ]
});
6. Promise 的错误处理
- 使用
.catch()
捕获链式调用中的任何错误。 - 也可以在
.then()
中传入第二个参数处理错误。
fetchData()
.then((data) => {
console.log(data);
throw new Error("Something went wrong!"); // 抛出错误
})
.catch((error) => {
console.error(error); // 捕获错误
});
7. Promise 与异步函数(Async/Await)
async/await
是 Promise 的语法糖,使异步代码看起来像同步代码。async
函数返回一个 Promise。await
用于等待 Promise 完成。
const fetchData = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve("Data fetched!");
}, 1000);
});
};
async function getData() {
try {
const result = await fetchData();
console.log(result); // Data fetched!
} catch (error) {
console.error(error);
}
}
getData();
8. 总结
- Promise 是 JavaScript 中处理异步操作的核心机制。
- 通过
.then()
、.catch()
和.finally()
可以优雅地处理异步操作的结果和错误。 async/await
进一步简化了 Promise 的使用,使代码更易读。- 掌握 Promise 是理解现代 JavaScript 异步编程的关键。
9. 实际应用场景
- 从 API 获取数据。
- 读取文件或数据库。
- 定时任务(如
setTimeout
)。 - 多个异步操作的并行或顺序执行。
通过合理使用 Promise,可以显著提升代码的可读性和可维护性。