Promise概念与状态
2025年3月7日大约 5 分钟
Promise概念与状态
Promise是一个代表异步操作最终完成或失败的对象。本文将介绍Promise的基本概念、三种状态(pending、fulfilled、rejected)以及如何创建和使用Promise对象。
Promise 的基本概念
Promise 是 JavaScript 中处理异步操作的一种方式,它提供了比传统回调函数更优雅的解决方案。Promise 可以帮助我们避免回调地狱(callback hell),使异步代码更易于理解和维护。
Promise 的特点
- 状态不可逆:Promise 一旦从等待状态变成其他状态就不能再改变
- 链式调用:Promise 可以通过
.then()
方法链式调用,简化异步流程 - 错误处理:Promise 提供统一的错误处理机制
- 异步操作封装:将异步操作封装成 Promise 对象,使代码更具可读性
为什么需要 Promise
在 Promise 出现之前,JavaScript 中处理异步操作主要依赖回调函数,这种方式在处理复杂异步流程时会导致代码嵌套过深,难以维护:
// 回调地狱示例
getData(function(a) {
getMoreData(a, function(b) {
getMoreData(b, function(c) {
getMoreData(c, function(d) {
getMoreData(d, function(e) {
// ...处理数据
});
});
});
});
});
使用 Promise 可以将上述代码改写为更加清晰的形式:
getData()
.then(a => getMoreData(a))
.then(b => getMoreData(b))
.then(c => getMoreData(c))
.then(d => getMoreData(d))
.then(e => {
// ...处理数据
})
.catch(error => {
// 统一处理错误
console.error('出错了:', error);
});
Promise 的三种状态
Promise 对象有三种状态:
- pending(等待中):初始状态,既不是成功也不是失败
- fulfilled(已成功):操作成功完成
- rejected(已失败):操作失败

状态转换规则
- Promise 对象的状态只能从 pending 变为 fulfilled 或从 pending 变为 rejected
- 一旦状态改变,就不会再变(不可逆)
- 状态的改变是通过 resolve 和 reject 函数来实现的
// 状态示例
const promise1 = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
resolve('成功'); // 将状态从 pending 改为 fulfilled
}, 1000);
});
const promise2 = new Promise((resolve, reject) => {
// 异步操作
setTimeout(() => {
reject(new Error('失败')); // 将状态从 pending 改为 rejected
}, 1000);
});
创建 Promise
基本语法
Promise 构造函数接收一个执行器函数(executor),该函数接收两个参数:
const promise = new Promise((resolve, reject) => {
// 异步操作
if (/* 操作成功 */) {
resolve(value); // 成功,传递结果
} else {
reject(error); // 失败,传递错误
}
});
resolve
函数:将 Promise 状态从 pending 改为 fulfilled,并将异步操作的结果作为参数传递出去reject
函数:将 Promise 状态从 pending 改为 rejected,并将异步操作的错误作为参数传递出去
实际示例
模拟网络请求
function fetchData(url) {
return new Promise((resolve, reject) => {
// 模拟网络请求
setTimeout(() => {
if (url.includes('success')) {
resolve({ data: '请求成功的数据', status: 200 });
} else {
reject(new Error('网络请求失败'));
}
}, 2000);
});
}
// 使用 Promise
fetchData('https://api.example.com/success')
.then(response => {
console.log('成功:', response);
})
.catch(error => {
console.error('失败:', error);
});
读取文件(Node.js 环境)
const fs = require('fs');
function readFile(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, 'utf8', (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
}
// 使用 Promise
readFile('example.txt')
.then(content => {
console.log('文件内容:', content);
})
.catch(error => {
console.error('读取文件失败:', error);
});
Promise 的方法
实例方法
Promise 实例有以下方法:
- then(onFulfilled, onRejected):添加解决(fulfilled)和拒绝(rejected)回调到 Promise,返回一个新的 Promise
- catch(onRejected):添加一个拒绝(rejected)回调到 Promise,返回一个新的 Promise
- finally(onFinally):添加一个回调,在 Promise 结束时调用,无论结果是 fulfilled 还是 rejected
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('成功');
}, 1000);
});
promise
.then(value => {
console.log(value); // 输出: 成功
return '新值';
})
.then(value => {
console.log(value); // 输出: 新值
throw new Error('出错了');
})
.catch(error => {
console.error(error.message); // 输出: 出错了
})
.finally(() => {
console.log('无论成功还是失败都会执行'); // 总是会执行
});
静态方法
Promise 类有以下静态方法:
- Promise.resolve(value):返回一个以给定值解析后的 Promise 对象
- Promise.reject(reason):返回一个带有拒绝原因的 Promise 对象
- Promise.all(iterable):等待所有 Promise 都成功,或有一个失败
- Promise.race(iterable):返回一个 Promise,一旦迭代器中的某个 Promise 解决或拒绝,就采用第一个 Promise 的值作为它的值
- Promise.allSettled(iterable):等待所有 Promise 都完成(无论是成功还是失败)
- Promise.any(iterable):接收一组 Promise 实例,只要其中的一个 Promise 成功,就返回那个成功的 Promise
这些静态方法将在后续章节中详细介绍。
Promise 的状态检查
虽然 Promise 的状态是内部属性,无法直接访问,但我们可以通过以下方式间接检查状态:
function checkPromiseState(promise) {
const state = {};
// 创建一个已解决的 Promise
const resolvedPromise = Promise.resolve();
// 创建一个已拒绝的 Promise
const rejectedPromise = Promise.reject().catch(() => {});
return Promise.race([
promise.then(
() => 'fulfilled',
() => 'rejected'
),
resolvedPromise.then(() => {
if (state.status) return state.status;
return 'pending';
})
]).then(result => {
state.status = result;
return state.status;
});
}
// 使用示例
const pendingPromise = new Promise(() => {});
const fulfilledPromise = Promise.resolve();
const rejectedPromise = Promise.reject().catch(() => {});
checkPromiseState(pendingPromise).then(state => console.log('Pending Promise:', state));
checkPromiseState(fulfilledPromise).then(state => console.log('Fulfilled Promise:', state));
checkPromiseState(rejectedPromise).then(state => console.log('Rejected Promise:', state));
Promise 的常见错误
1. 忘记返回 Promise
// 错误示例
function fetchData() {
// 没有 return,导致调用者无法获取 Promise
fetch('https://api.example.com/data');
}
// 正确示例
function fetchData() {
return fetch('https://api.example.com/data');
}
2. 未处理 Promise 拒绝
// 错误示例 - 未捕获拒绝
const promise = new Promise((resolve, reject) => {
reject(new Error('出错了'));
});
promise.then(data => console.log(data));
// Uncaught (in promise) Error: 出错了
// 正确示例
promise
.then(data => console.log(data))
.catch(error => console.error('捕获到错误:', error.message));
3. Promise 嵌套(没有正确使用链式调用)
// 错误示例 - Promise 嵌套
fetchData().then(result => {
fetchMoreData(result).then(moreResult => {
// 嵌套的 Promise
});
});
// 正确示例 - 使用链式调用
fetchData()
.then(result => fetchMoreData(result))
.then(moreResult => {
// 处理 moreResult
});
总结
Promise 是 JavaScript 中处理异步操作的强大工具,它通过三种状态(pending、fulfilled、rejected)来表示异步操作的不同阶段。
主要优点:
- 链式调用使异步代码更加清晰
- 统一的错误处理机制
- 避免回调地狱
- 更好的异步流程控制
在接下来的章节中,我们将深入探讨 Promise 的更多高级用法,包括链式调用、错误处理、Promise 组合等内容。