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 进一步简化复杂逻辑 。

相关推荐
楊无好6 分钟前
react中props的使用
前端·react.js·前端框架
一个处女座的程序猿O(∩_∩)O11 分钟前
Vue-Loader 深度解析:原理、使用与最佳实践
前端·javascript·vue.js
一点一木24 分钟前
火山方舟 Responses API 实战指南:从概念到「公司尽调 Dossier 生成器」
前端·人工智能·api
还是大剑师兰特1 小时前
TypeScript 面试题及详细答案 100题 (91-100)-- 工程实践与框架集成
前端·javascript·typescript·1024程序员节
用户47949283569151 小时前
typeof null === 'object':JavaScript 最古老的 bug 为何 30 年无法修复?
前端·javascript·面试
__WanG1 小时前
如何编写标准StatefulWidget页面
前端·flutter
非凡ghost1 小时前
By Click Downloader(下载各种在线视频) 多语便携版
前端·javascript·后端
非凡ghost1 小时前
VisualBoyAdvance-M(GBA模拟器) 中文绿色版
前端·javascript·后端
非凡ghost1 小时前
K-Lite Mega/FULL Codec Pack(视频解码器)
前端·javascript·后端
LinXunFeng2 小时前
Flutter 多仓库本地 Monorepo 方案与体验优化
前端·flutter·架构