Promise 是代表异步操作状态的原生对象,有 pending、fulfilled、rejected 三种不可逆状态;通过 new Promise(executor) 创建,executor 同步执行并接收 resolve/reject;.then()/.catch() 链式返回新 Promise,需始终捕获错误;Promise.all() 全成功才 resolve,Promise.race() 取首个 settle 结果,Promise.allSettled() 和 Promise.any() 各适用不同容错场景。

Promise 是 JavaScript 中用于管理异步操作的原生对象,它不是语法糖,也不是回调函数的替代品——它是异步状态的容器,代表一个“尚未完成但将来会有结果”的操作。
Promise 的三种状态和基本构造
Promise 实例创建后始终处于以下三种状态之一:pending(进行中)、fulfilled(已成功)、rejected(已失败)。状态一旦改变(pending → fulfilled 或 pending → rejected),就不可逆。
用 new Promise() 构造时,必须传入一个执行器函数,该函数接收两个参数:resolve 和 reject,它们都是函数:
const p = new Promise((resolve, reject) => {
setTimeout(() => {
const success = Math.random() > 0.5;
if (success) {
resolve('操作成功'); // 触发 fulfilled 状态
} else {
reject(new Error('操作失败')); // 触发 rejected 状态
}
}, 100);
});-
resolve(value):将 Promise 变为fulfilled,其值为value;若传入另一个 Promise,当前 Promise 会等待它完成 -
reject(reason):将 Promise 变为rejected,reason通常是一个Error实例,便于追踪堆栈 - 执行器函数是同步运行的,但内部通常包裹异步逻辑(如
setTimeout、fetch、XMLHttpRequest)
用 .then() 和 .catch() 链式处理结果
.then() 接收两个可选回调:onFulfilled 和 onRejected;.catch() 等价于 .then(null, onRejected)。链式调用的关键在于:每个 .then() 或 .catch() 都返回一个新的 Promise。
立即学习“Java免费学习笔记(深入)”;
动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包
fetch('/api/data')
.then(response => {
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return response.json(); // 返回 Promise,自动被下一个 .then 处理
})
.then(data => console.log(data))
.catch(err => console.error('出错了:', err.message));- 如果
.then()回调返回一个普通值(如字符串、数字),下一个.then()会立即以该值为参数执行 - 如果返回一个 Promise,下一个
.then()会等待它fulfilled后再执行 -
.catch()会捕获前面所有环节抛出的错误(包括throw和reject),但不会捕获在自身回调里抛出的新错误——除非后面再接一个.catch() - 不要混用
.then(success, fail)和.catch(),否则success中抛出的错误会被.catch()捕获,而fail中的错误不会
常见陷阱:未捕获的 rejected Promise
当 Promise 被 reject 但没有任何 .catch() 或第二个 .then() 参数处理时,浏览器或 Node.js 会抛出 Uncaught (in promise) Error 警告,且该错误无法被 try/catch 捕获。
- 避免写成:
someAsyncFn().then(handleSuccess);—— 缺少错误处理分支 - 推荐写法:
someAsyncFn().then(handleSuccess).catch(handleError); - 在顶层异步流程(如事件处理器、模块初始化)中,务必确保 Promise 链有终点
.catch(),或使用async/await+try/catch - Node.js 中可通过监听
process.on('unhandledRejection', ...)做兜底日志,但不能代替显式错误处理
Promise.all() 和 Promise.race() 的实际取舍
它们适用于多个异步任务的组合控制,但行为差异极大,选错会导致逻辑错误。
const promises = [
fetch('/api/user'),
fetch('/api/posts'),
fetch('/api/settings')
];
// Promise.all():全部成功才 resolve,任一 reject 就立刻 reject(“全有或全无”)
Promise.all(promises)
.then(([user, posts, settings]) => { / 所有数据就绪 / })
.catch(err => { / 任意一个失败,整个失败 / });
// Promise.race():谁先 settle(fulfill 或 reject),就用谁的结果
Promise.race([fetch('/api/fast'), fetch('/api/slow').then(r => r.json())])
.then(data => console.log('最快的那个:', data))
.catch(err => console.warn('最快的那个也失败了:', err));
-
Promise.allSettled()更稳妥:不管成功失败,都等全部结束,返回每个 Promise 的状态对象,适合“尽力而为”场景 -
Promise.any()(ES2021):只要有一个 fulfilled 就 resolve;全部 rejected 才 reject,适合降级请求(如多 CDN 获取资源) - 注意:
Promise.all()中的 Promise 是并发发起的,不是串行;想串行请用reduce或for...of+await
Promise 的核心不在“怎么写”,而在“状态流转是否可控”——漏掉一个 .catch()、误用 Promise.all() 替代 allSettled()、在执行器里忘记调用 resolve 或 reject,都会让异步流静默失效或难以调试。










