Promise 是 JavaScript 中处理异步操作的核心机制,通过状态管理和链式调用解决了回调地狱问题,提升了代码可读性和可维护性。以下是其核心要点和用法详解:
🔮 一、Promise 的本质与状态
-
定义
Promise 是一个表示异步操作最终结果的对象,其状态不可逆:
- ⏳ Pending(进行中):初始状态。
- ✅ Fulfilled(已成功) :异步操作成功完成,通过
resolve(value)
触发。 - ❌ Rejected(已失败) :异步操作失败,通过
reject(reason)
或抛出异常触发 。
-
状态特性
- 状态一旦从 Pending 变为 Fulfilled 或 Rejected,便不可再改变 。
- 构造函数中若同时调用
resolve
和reject
,仅第一次调用有效 。
⚙️ 二、核心方法与使用
-
创建 Promise
通过
new Promise()
传入执行器函数(同步执行):javascriptconst promise = new Promise((resolve, reject) => { setTimeout(() => resolve('成功'), 1000); // 1秒后成功 });
-
**处理结果:
then()
与catch()
**-
then(onFulfilled, onRejected)
:注册成功/失败回调,返回新 Promise 支持链式调用 。inipromise.then(value => console.log(value)) // 输出"成功" .catch(err => console.error(err));
-
catch(onRejected)
:捕获错误,等同于then(null, onRejected)
。
-
-
链式调用原理
-
每次
then
返回新 Promise,其状态由回调返回值决定:- 返回非 Promise 值 → 新 Promise 成功(值为返回值)
- 返回 Promise → 新 Promise 继承该 Promise 状态 。
typescriptnew Promise(resolve => resolve(10)) .then(num => num * 2) // 返回20 → 新Promise成功 .then(num => Promise.reject('失败')) // 返回失败Promise .catch(err => console.log(err)); // 输出"失败"
-
🌟 三、静态方法与应用场景
-
**
Promise.all([p1, p2, ...])
**- 全部成功才成功:返回所有结果的数组。
- 任一失败则失败:返回第一个失败原因 。
typescriptPromise.all([fetch(url1), fetch(url2)]) .then(results => console.log(results)) // [res1, res2] .catch(err => console.log('首个失败请求', err));
-
**
Promise.race([p1, p2, ...])
**- 首个完成的状态决定结果:适用于超时控制 。
typescriptconst timeout = new Promise((_, reject) => setTimeout(() => reject('超时'), 5000)); Promise.race([fetch(url), timeout]) .then(data => useData(data)) .catch(() => fallback());
-
其他静态方法
Promise.resolve(value)
:返回成功状态的 Promise。Promise.reject(reason)
:返回失败状态的 Promise 。Promise.allSettled([p1, p2])
:等待所有完成,返回状态结果数组(ES2020) 。
🛡️ 四、错误处理与最佳实践
-
统一错误捕获
使用
catch
捕获链式调用中任意环节的错误:scssfetchData() .then(process) .then(updateUI) .catch(err => showError(err)); // 统一处理所有错误
-
避免常见陷阱
- 回调中抛错 :自动触发
catch
(等效于reject
)。 - 未捕获的拒绝 :使用
.catch()
或process.on('unhandledRejection')
(Node.js)。
- 回调中抛错 :自动触发
⚡ 五、底层原理与微任务
- 事件循环机制 :Promise 回调属于微任务 (Microtask),优先级高于宏任务(如
setTimeout
)。 - 状态变更流程 :
resolve/reject
→ 将回调推入微任务队列 → 当前宏任务结束后立即执行 。
💎 总结与最佳实践
-
适用场景:
- 替代回调嵌套(如多层网络请求)。
- 并行任务管理(
Promise.all
)或竞态任务(Promise.race
)。
-
核心原则:
- 使用链式调用替代嵌套。
- 始终用
catch
捕获错误。 - 避免在
then
中混合同步/异步操作(用Promise.resolve
包装同步值)。
-
进阶工具 :
async/await
是 Promise 的语法糖,提供更同步化的写法 。
通过合理使用 Promise 的状态机模型、链式调用和静态方法,可显著提升异步代码的健壮性和可读性。实践中可结合
async/await
进一步简化复杂逻辑 。