js之Promise

Promise 是 JavaScript 中处理异步操作的核心机制,通过状态管理和链式调用解决了回调地狱问题,提升了代码可读性和可维护性。以下是其核心要点和用法详解:


🔮 ​一、Promise 的本质与状态

  1. 定义

    Promise 是一个表示异步操作最终结果的对象,其状态不可逆:

    • Pending(进行中)​:初始状态。
    • Fulfilled(已成功)​ :异步操作成功完成,通过 resolve(value) 触发。
    • Rejected(已失败)​ :异步操作失败,通过 reject(reason) 或抛出异常触发 。
  2. 状态特性

    • 状态一旦从 Pending 变为 Fulfilled 或 Rejected,便不可再改变 。
    • 构造函数中若同时调用 resolvereject,仅第一次调用有效 。

⚙️ ​二、核心方法与使用

  1. 创建 Promise

    通过 new Promise() 传入执行器函数(同步执行):

    javascript 复制代码
    const promise = new Promise((resolve, reject) => {
      setTimeout(() => resolve('成功'), 1000); // 1秒后成功
    });
  2. ​**处理结果:then()catch()**​

    • then(onFulfilled, onRejected):注册成功/失败回调,返回新 Promise​ 支持链式调用 。

      ini 复制代码
      promise.then(value => console.log(value)) // 输出"成功"
             .catch(err => console.error(err));
    • catch(onRejected):捕获错误,等同于 then(null, onRejected)

  3. 链式调用原理

    • 每次 then 返回新 Promise,其状态由回调返回值决定:

      • 返回非 Promise 值 → 新 Promise 成功(值为返回值)
      • 返回 Promise → 新 Promise 继承该 Promise 状态 。
      typescript 复制代码
      new Promise(resolve => resolve(10))
        .then(num => num * 2)       // 返回20 → 新Promise成功
        .then(num => Promise.reject('失败')) // 返回失败Promise
        .catch(err => console.log(err)); // 输出"失败"

🌟 ​三、静态方法与应用场景

  1. ​**Promise.all([p1, p2, ...])**​

    • 全部成功才成功:返回所有结果的数组。
    • 任一失败则失败:返回第一个失败原因 。
    typescript 复制代码
    Promise.all([fetch(url1), fetch(url2)])
      .then(results => console.log(results)) // [res1, res2]
      .catch(err => console.log('首个失败请求', err));
  2. ​**Promise.race([p1, p2, ...])**​

    • 首个完成的状态决定结果:适用于超时控制 。
    typescript 复制代码
    const timeout = new Promise((_, reject) => 
      setTimeout(() => reject('超时'), 5000));
    Promise.race([fetch(url), timeout])
      .then(data => useData(data))
      .catch(() => fallback());
  3. 其他静态方法

    • Promise.resolve(value):返回成功状态的 Promise。
    • Promise.reject(reason):返回失败状态的 Promise 。
    • Promise.allSettled([p1, p2]):等待所有完成,返回状态结果数组(ES2020) 。

🛡️ ​四、错误处理与最佳实践

  1. 统一错误捕获

    使用 catch 捕获链式调用中任意环节的错误:

    scss 复制代码
    fetchData()
      .then(process)
      .then(updateUI)
      .catch(err => showError(err)); // 统一处理所有错误
  2. 避免常见陷阱

    • 回调中抛错 :自动触发 catch(等效于 reject)。
    • 未捕获的拒绝 :使用 .catch()process.on('unhandledRejection')(Node.js)。

⚡ ​五、底层原理与微任务

  • 事件循环机制 :Promise 回调属于微任务 (Microtask),优先级高于宏任务(如 setTimeout)。
  • 状态变更流程
    resolve/reject → 将回调推入微任务队列 → 当前宏任务结束后立即执行 。

💎 ​总结与最佳实践

  • 适用场景​:

    • 替代回调嵌套(如多层网络请求)。
    • 并行任务管理(Promise.all)或竞态任务(Promise.race)。
  • 核心原则​:

    1. 使用链式调用替代嵌套。
    2. 始终用 catch 捕获错误。
    3. 避免在 then 中混合同步/异步操作(用 Promise.resolve 包装同步值)。
  • 进阶工具 ​:
    async/await 是 Promise 的语法糖,提供更同步化的写法 。

通过合理使用 Promise 的状态机模型、链式调用和静态方法,可显著提升异步代码的健壮性和可读性。实践中可结合 async/await 进一步简化复杂逻辑 。

相关推荐
QQ1__8115175155 小时前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态5 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子5 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室5 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI5 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing5 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者5 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册5 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李5 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢5 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web