【前端】ES6 引入的异步编程解决方案Promise 详解

news2025/4/27 19:02:25

Promise 详解

在这里插入图片描述


1. 基本概念
  • 定义:Promise 是 ES6 引入的异步编程解决方案,表示一个异步操作的最终完成(或失败)及其结果值
  • 核心作用:替代回调函数,解决“回调地狱”问题,提供更清晰的异步流程控制。

2. 核心状态

Promise 有三种状态:

状态描述
pending初始状态,既未成功也未失败。
fulfilled操作成功完成,Promise 结果可通过 .then() 获取。
rejected操作失败,错误信息可通过 .catch() 获取。

3. 核心方法
// 基本语法
const promise = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    const success = true;
    if (success) {
      resolve("成功"); // 改变为 fulfilled
    } else {
      reject("失败"); // 改变为 rejected
    }
  }, 1000);
});

// 使用 then/catch
promise
  .then((value) => console.log(value)) // 成功时执行
  .catch((error) => console.error(error)) // 失败时执行
  .finally(() => console.log("结束")); // 无论成功失败均执行

4. 核心特性
(1) 链式调用(Chaining)
promise
  .then((result) => {
    console.log(result); // 第一个 then
    return result * 2; // 返回值传递给下一个 then
  })
  .then((newResult) => console.log(newResult)); // 第二个 then
(2) 错误传递
  • 若某一层 .then() 抛出错误或调用 reject,后续 .then() 会跳过,直接进入最近的 .catch()
promise
  .then(() => {
    throw new Error("出错了"); // 触发错误
  })
  .then(() => console.log("不会执行"))
  .catch((err) => console.error(err)); // 捕获错误
(3) 微任务队列
  • Promise 的回调(.then/.catch)会被放入微任务队列,优先于宏任务(如 setTimeout)执行:
setTimeout(() => console.log("宏任务"), 0); // 后执行
Promise.resolve().then(() => console.log("微任务")); // 先执行

5. 静态方法
方法作用
Promise.all()等待所有 Promise 完成,返回成功结果数组,若有一个失败则立即返回错误。
Promise.race()哪个 Promise 先完成,就返回其结果(成功或失败)。
Promise.resolve()将现有值或 Promise 转换为 Promise 对象。
Promise.reject()直接生成一个 rejected 状态的 Promise。
// 示例:Promise.all
Promise.all([p1, p2, p3])
  .then((results) => console.log(results)) // [result1, result2, result3]
  .catch((err) => console.error(err));

// 示例:Promise.race
Promise.race([slowPromise, fastPromise])
  .then((result) => console.log("最快完成的结果:", result));

6. 异常处理
  • 未捕获的 Rejection:若 Promise 抛出错误但未被 .catch() 捕获,会触发全局事件 unhandledrejection
    window.addEventListener('unhandledrejection', (event) => {
      console.error('未捕获的错误:', event.reason);
      event.preventDefault(); // 阻止默认的控制台报错
    });
    

7. async/await 语法糖
  • async/await 是基于 Promise 的语法糖,使异步代码更接近同步写法:
async function fetchData() {
  try {
    const response = await fetchAPI(); // 等待 Promise 完成
    console.log(response.data);
  } catch (error) {
    console.error(error);
  } finally {
    console.log("完成"); // 可选
  }
}

8. 常见陷阱
  1. 过早 resolve/reject
    如果在 Promise 构造函数中直接调用 resolve/reject,会立即执行,而非等待异步操作:

    // 错误示例:resolve 立即执行
    new Promise((resolve) => {
      resolve("提前完成"); // 这里会立即 resolve
      setTimeout(() => console.log("延迟操作"), 1000);
    });
    
  2. 遗忘 error 处理
    未在链式调用中添加 .catch() 可能导致错误未被捕获。

  3. this 指向问题
    .then() 中使用箭头函数可避免 this 丢失:

    const obj = {
      asyncMethod() {
        return new Promise(resolve => resolve("数据"));
      },
      process() {
        this.asyncMethod()
          .then(data => console.log(this)) // `this` 可能为 undefined
      }
    };
    // 解决方案:绑定 this 或使用箭头函数
    

9. 最佳实践
  1. 避免嵌套回调:使用链式调用或 async/await
  2. 统一错误处理:在顶层添加 .catch() 或全局监听 unhandledrejection
  3. 合理拆分 Promise:将复杂逻辑拆分为多个小 Promise,便于调试。
  4. 结合 async/await 提升可读性
    async function example() {
      const data = await fetchAPI(); // 等待完成再继续
      processData(data);
    }
    

10. 与 Callback 的对比
特性PromiseCallback
可读性链式调用更清晰嵌套回调易形成“回调地狱”
错误处理集中通过 .catch() 处理需在每个回调中单独处理错误
控制流支持 Promise.all 等批量操作需手动管理多个回调的完成状态
兼容性需 polyfill 旧版浏览器全局可用,无需额外支持

总结

Promise 是现代 JavaScript 异步编程的核心工具,通过清晰的状态管理和链式调用,极大提升了代码的可维护性。结合 async/await,可以进一步简化异步逻辑,避免回调地狱,是处理异步操作的首选方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2343122.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

const(C++)

打印出来的结果是 a是12 *p是200 const修饰指针 const修饰引用

python21-循环小作业

课程:B站大学 记录python学习,直到学会基本的爬虫,使用python搭建接口自动化测试就算学会了,在进阶webui自动化,app自动化 循环语句小作业 for-in作业斐波那契 for 固定数值计算素数字符统计数字序列range 函数 水仙花…

小白电路设计-设计11-恒功率充电电路设计

介绍 作为电子信息工程的我,电路学习是一定要学习的,可惜目前作为EMC测试工程师,无法兼顾太多,索性不如直接将所学的知识进行运用,并且也可以作为契机,进行我本人的个人提升。祝大家与我一起进行提升。1.本…

Spring AI 快速入门:从环境搭建到核心组件集成

Spring AI 快速入门:从环境搭建到核心组件集成 一、前言:Java开发者的AI开发捷径 对于Java生态的开发者来说,将人工智能技术融入企业级应用往往面临技术栈割裂、依赖管理复杂、多模型适配困难等挑战。Spring AI的出现彻底改变了这一局面——…

http://noi.openjudge.cn/——2.5基本算法之搜索——200:Solitaire

文章目录 题目宽搜代码总结 题目 总时间限制: 5000ms 单个测试点时间限制: 1000ms 内存限制: 65536kB 描述 Solitaire is a game played on a chessboard 8x8. The rows and columns of the chessboard are numbered from 1 to 8, from the top to the bottom and from left t…

架构师面试(三十六):广播消息

题目 在像 IM、短视频、游戏等实时在线类的业务系统中,一般会有【广播消息】业务,这类业务具有瞬时高流量的特点。 在对【广播消息】业务实现时通常需要同时写 “系统消息库” 和更新用户的 “联系人库” 的操作,用户的联系人表中会有未读数…

TortoiseGit使用图解

前言 记录GitTortoiseGit使用,记录下开发中常用命令,健忘时用到方知好。 TortoiseGit使用 图解 commit-提交代码 pull-拉取远程分支最新代码 push-将本地分支代码推送到远程分支 show log-查看分支提交记录 show log - 切换分支查看 show log - 远程分…

【时时三省】(C语言基础)循环程序举例

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 例题: 用公式4/π≈1-3/1+5/1-7/1+...求π的近似值,直到发现某一项的绝对值小于10的-6次方为止(该项不累加)。 解题思路: 这是求值的近似方法中的一种。求π值可以用不同的近似方法。如下面的表达式都可以…

珍爱网:从降本增效到绿色低碳,数字化新基建价值凸显

2024年12月24日,法大大联合企业绿色发展研究院发布《2024签约减碳与低碳办公白皮书》,深入剖析电子签在推动企业绿色低碳转型中的关键作用,为企业实现环境、社会和治理(ESG)目标提供新思路。近期,法大大将陆…

电子电子架构 --- 主机厂视角下ECU开发流程

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

PyQt6基础_QTableWidget

目录 描述: 代码 演示 描述: 1 单击选中一行 2 右键菜单 3 填充数据 4 提取行数据 5 删除行数据 代码 from PyQt6.QtCore import (Qt ) from PyQt6.QtGui import ( QAction ) from PyQt6.QtWidgets import (QApplication,QAbstractItemView,QL…

uniapp 上传二进制流图片

文章目录 场景🟢一、步骤1.1、选择图片1.2、 读取图片为二进制数据1.3、上传二进制数据到服务器 🟢二、项目案例2.1、替换头像案例2.1、uView u-upload 上传封面 🟢 三、关键注意事项3.1 二进制流与 FormData 区别3.2 性能优化3.3 跨平台适配…

赛灵思 XCKU115-2FLVB2104I Xilinx Kintex UltraScale FPGA

XCKU115-2FLVB2104I 是 AMD Xilinx Kintex UltraScale FPGA,基于 20 nm 先进工艺,提供高达 1 451 100 个逻辑单元(Logic Cells),77 721 600 bit 的片上 RAM 资源,以及 5 520 个 DSP 切片(DSP48E…

Unreal Niagara制作SubUV贴图翻页动画

SubUV翻页动画是游戏中的常见功能,通过对每一小块UV进行移动可以模拟动画效果,接下来对下图进行SubUV动画的制作。 (金币测试图下载地址:https://download.csdn.net/download/grayrail/90684422) 最终效果如下: 1.…

「零配置陷阱」:现代全栈工具链的复杂度管控实践

一、工具链膨胀的「死亡螺旋」 2024年典型全栈项目的初始化噩梦: $ npm create vitelatest ✔ Project name: … demo ✔ Select a framework: › React ✔ Select a variant: › TypeScript SWC ✔ Install shadcn/ui? … Yes ✔ Add Storybook? … Yes ✔ Co…

金仓数据库KingbaseES技术实践类深度剖析与实战指南

一、语法兼容及迁移实战 (一)语法兼容的多元魅力 在当今多元化的数据库应用环境中,金仓数据库管理系统KingbaseES凭借其卓越的语法兼容能力脱颖而出。它采用的融合数据库架构,通过多语法体系一体化架构,实现了对Orac…

基于ssm的个人博客管理系统(源码+数据库+万字文档)

57基于ssm的个人博客管理系统:前端jsp、jquery、easyui,后端 spring、mybatis、maven,集成个人博客浏览、详情查看、博客发布、富文本编辑、评论等功能于一体的系统。 ## 功能介绍 ### 用户 - 首页:博客列表、博客详情、关键词…

综述 | GUI Agent:让AI学会「玩手机」的新革命

想象一下,你的手机里住着一个隐形助理:你说“把亮度调到50%”,它自动操作;你说“下载最新游戏”,它一键完成。这就是GUI智能体——一种能“看懂”屏幕并操作的AI。 论文:A Survey on (M)LLM-Based GUI Agen…

Canvas入门教程!!【Canvas篇二】

没有一朵花,从一开始就是花。 目录 translate() 方法:rotate() 方法:scale() 方法: translate() 方法: Canvas 2D API 的 CanvasRenderingContext2D.translate() 方法用于对当前网格添加平移变换。 translate() 方法通…

【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)

【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题) 目录 【中级软件设计师】函数调用 —— 传值调用和传地址调用 (附软考真题)一、历年真题二、考点:函数调用 —— 传值调用和传地址调用🔺1、传值调用🔺2、传引用(地址)调…