什么是 Promise?
基本概念
Promise 是一个构造函数,创建出的对象代表一个异步操作及其最终完成(成功或失败)后的结果。它是一个可链接、可组合的抽象值,用于表示一个未来可能完成也可能失败的操作,以及该操作完成后所得到的数据(或错误信息)。
Promise 对象有以下三个关键特性:
-
状态(State):Promise 有三种状态,分别是 pending(待定)、fulfilled(已成功)和 rejected(已失败)。状态一旦确定(即从 pending 转变为 fulfilled 或 rejected),就永远不会再改变。
-
值(Value):当 Promise 处于 fulfilled 状态时,它关联一个成功的值(通常是一个返回结果)。当处于 rejected 状态时,它关联一个错误原因(通常是一个异常对象)。
-
回调注册(Callbacks):Promise 提供了 then 和 catch 方法,用于注册当 Promise 状态改变时应执行的回调函数。then 接收两个参数,分别对应 Promise 成功和失败时的回调;catch 仅用于捕获错误,相当于 then(null, rejectHandler)。
为什么使用 Promise?
使用 Promise 的好处:
解决回调地狱(Callback Hell):通过链式调用 then,Promise 允许开发者以扁平化的、易于阅读的方式组织异步代码,消除了深度嵌套的回调函数带来的复杂性和难以维护性。
更好的错误处理:Promise 提供了统一的错误处理机制,通过在链尾添加 catch 或者在 then 中传入第二个回调函数,可以集中处理 Promise 链中任何位置可能出现的错误。
更丰富的控制能力:Promise 支持 all、race、any、finally 等方法,可以方便地处理多个并发 Promise 的结果,或者在 Promise 结束时执行清理操作,而不关心其最终状态。
与现有/未来异步API的兼容性:许多现代 JavaScript 库和原生浏览器 API 已经采用 Promise 作为异步操作的标准返回类型,学习和使用 Promise 有助于无缝对接这些接口。
如何使用 Promise:
以下是一个简单的 Promise 使用示例,假设有一个模拟的异步操作 fetchData:
function fetchData(url) {
return new Promise((resolve, reject) => {
// 模拟异步操作,如 AJAX 请求
setTimeout(() => {
if (/* 请求成功 */) {
resolve({ data: 'Some fetched data' });
} else {
reject(new Error('Failed to fetch data'));
}
}, 1000);
});
}
// 使用 Promise
fetchData('https://example.com/data')
.then(data => {
console.log('Fetched data:', data);
// 在此处处理成功数据
})
.catch(error => {
console.error('Error fetching data:', error);
// 在此处处理错误情况
});
fetchData 函数返回一个新的 Promise,它通过构造函数接收一个执行器(executor)函数。执行器内部定义了异步操作,并在操作成功时调用 resolve 函数传递结果,失败时调用 reject 函数传递错误。
调用 fetchData 后,我们通过 .then 方法注册成功回调函数来处理预期的数据,通过 .catch 方法注册失败回调函数来处理可能出现的错误。