Promise详解:从回调地狱到优雅异步

Promise 详解

为什么需要 Promise

在实际开发中,我们经常需要处理异步操作链。例如:

  1. 通过 AJAX 请求获取用户 ID
  2. 根据 ID 请求用户名
  3. 根据用户名获取邮箱地址

使用传统回调函数会导致"回调地狱"(回调函数中嵌套回调函数),而 Promise 正是为了解决这个问题而诞生的。

Promise 基本使用

语法

Promise 接受一个函数作为参数,该函数包含两个参数:

  • resolve: 成功回调函数
  • reject: 失败回调函数

Promise 实例

每个 Promise 实例都有两个关键属性:

  • state: 表示当前状态
  • result: 存储操作结果

Promise 的三种状态

  1. pending (等待中)
  2. fulfilled (已成功)
  3. rejected (已失败)

状态改变方法

  • resolve(): 将状态改为 fulfilled
  • reject(): 将状态改为 rejected

注意:Promise 的状态改变是一次性的,不可逆转。

Promise 的方法

then 方法

  • 通过形参获取 Promise 对象的结果
  • 返回一个新的 Promise 实例(初始状态为 pending)
  • 如果 Promise 状态未改变,不会执行 then 中的方法
  • 可以通过 return 将返回的 Promise 实例状态改为 fulfilled
  • 如果代码出错,返回的 Promise 实例状态会改为 rejected

catch 方法

用于捕获和处理错误

async 和 await

async 函数

  • 返回值总是 Promise 对象
  • 结果由函数执行的返回值决定:
    • 返回非 Promise 值:成功状态
    • 返回 Promise 对象:继承该 Promise 的状态
    • 抛出异常:失败状态
javascript 复制代码
async function main() {
  // 1. 返回非 Promise 值(成功状态)
  // return "字符串/数字/布尔值";
  
  // 2. 返回 Promise 对象
  return new Promise((resolve, reject) => {
    resolve("OK"); // 成功状态
    // reject("Err"); // 失败状态
  });
  
  // 3. 抛出异常(失败状态)
  // throw "oh No";
}

await 表达式

  • 右侧表达式通常是 Promise 对象
  • 如果是 Promise 对象,返回其成功值
  • 如果是其他值,直接返回该值

注意事项:

  1. await 必须用在 async 函数中
  2. 如果 await 的 Promise 失败,会抛出异常
  3. 建议使用 try...catch 捕获错误

实践示例

javascript 复制代码
const fs = require("fs");
const util = require("util");
const mineReadFile = util.promisify(fs.readFile); // 转换为 Promise 形式

async function main() {
  try {
    let data1 = await mineReadFile("./resource/1.html");
    let data2 = await mineReadFile("./resource/2.html");
    let data3 = await mineReadFile("./resource/3.html");
  } catch(e) {
    console.log(e);
  }
}
相关推荐
码视野32 分钟前
基于 Spring Boot + Vue3 的【大学英语四六级 (CET-4/6) 作文智能评分与句式润色系统】设计与实现(含PRD/三端高保真源码/大屏)
java·前端·人工智能·spring boot·后端·vue3
大模型码小白38 分钟前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
m0_547486661 小时前
《JavaScript核心原理 》全套PPT课件2026
开发语言·javascript·ecmascript
xm_xm_xm_12 小时前
react17版本以前类组件常用操作
前端·javascript·react.js
ly76892 小时前
Web 性能优化实战:从 Core Web Vitals 到工程化性能治理
前端·性能优化
冬奇Lab3 小时前
一天一个开源项目(第200篇):next-forge - 生产级 Next.js SaaS 启动模板
前端·前端框架·开源
Profile排查笔记3 小时前
指纹浏览器怎么设置 IP?代理配置、检测与排错流程
前端·人工智能·后端·自动化
lzhdim3 小时前
13、JavaScript事件循环机制 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
liangshanbo12153 小时前
Vue 3 <script setup> 的本质原理是什么?它与普通 setup()有何区别?
前端·javascript·vue.js
IT_陈寒4 小时前
SpringBoot自动配置失效?你可能漏了这个小开关
前端·人工智能·后端