JS 入门通关手册(24):Promise:从回调地狱到异步优雅写法

回调函数虽然能实现异步,但一旦遇到多个有依赖的异步任务,就会变成嵌套多层的回调地狱,代码难读、难维护、难调试。

Promise 就是为了解决这个问题而生的。它不是新的异步功能,而是异步代码的管理方案,让异步代码可以像同步代码一样链式书写。


一、Promise 是什么?

一句话:Promise 是一个表示异步操作最终完成(或失败)的对象,它让你能把回调写法改成链式调用写法,彻底告别回调地狱。

它有三种状态:

  1. pending:等待中(初始状态)
  2. fulfilled:已成功(操作完成)
  3. rejected:已失败(操作出错)

特点:

  • 状态一旦改变,就凝固不变
  • 从 pending → fulfilled 或 pending → rejected
  • 改变后不可再修改

二、Promise 基本用法

1. 创建 Promise

javascript

运行

javascript 复制代码
const p = new Promise((resolve, reject) => {
  // 异步操作
  setTimeout(() => {
    // 成功
    resolve("数据拿到了");

    // 失败
    // reject("请求失败");
  }, 1000);
});

2. 使用 then 接收结果

javascript

运行

javascript 复制代码
p.then(res => {
  console.log("成功:", res);
}).catch(err => {
  console.log("失败:", err);
});

3. 封装一个异步请求(模拟接口)

javascript

运行

javascript 复制代码
function request(url) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (url) {
        resolve({ data: "用户数据", code: 200 });
      } else {
        reject("url 不能为空");
      }
    }, 1000);
  });
}

// 使用
request("/api/user")
  .then(res => console.log(res))
  .catch(err => console.log(err));

三、Promise 链式调用(核心:解决回调地狱)

这是 Promise 最强大的地方:then 可以返回新 Promise,继续 then。

对比回调地狱:

javascript

运行

javascript 复制代码
// 以前回调地狱
getID(function (id) {
  getUser(id, function (user) {
    getOrder(user, function (order) {
      console.log(order);
    });
  });
});

Promise 链式写法:

javascript

运行

javascript 复制代码
request("/id")
  .then(id => request("/user/" + id))
  .then(user => request("/order/" + user.id))
  .then(order => console.log(order))
  .catch(err => console.log("出错:", err));

清爽、线性、可维护!


四、Promise 常用 API

1. Promise.then()

成功时执行,可返回新 Promise 继续链式。

2. Promise.catch()

捕获任何环节的错误。

3. Promise.finally()

无论成功失败,一定执行(常用于关闭加载)。

javascript

运行

javascript 复制代码
request("/api")
  .then(res => {})
  .catch(err => {})
  .finally(() => {
    console.log("结束");
  });

4. Promise.all()

多个请求并行,全部成功才成功。

javascript

运行

javascript 复制代码
const p1 = request("/api1");
const p2 = request("/api2");

Promise.all([p1, p2])
  .then(res => console.log(res[0], res[1]))
  .catch(err => console.log("有一个失败就失败"));

5. Promise.race()

谁先完成就用谁(不管成功失败)。

javascript

运行

javascript 复制代码
Promise.race([p1, p2]).then(res => console.log("最快的结果"));

6. Promise.resolve() / Promise.reject()

快速返回成功 / 失败的 Promise。

javascript

运行

javascript 复制代码
Promise.resolve(123).then(res => console.log(res));

五、Promise 手写小案例(模拟真实接口)

javascript

运行

javascript 复制代码
// 模拟获取用户ID
function getUserId() {
  return new Promise(resolve => {
    setTimeout(() => resolve(1001), 1000);
  });
}

// 模拟获取用户信息
function getUserInfo(id) {
  return new Promise(resolve => {
    setTimeout(() => resolve({ id, name: "张三" }), 1000);
  });
}

// 模拟获取订单
function getOrder(user) {
  return new Promise(resolve => {
    setTimeout(() => resolve({ orderId: 1, userId: user.id }), 1000);
  });
}

// 链式调用(完全没有嵌套)
getUserId()
  .then(id => getUserInfo(id))
  .then(user => getOrder(user))
  .then(order => console.log("最终订单:", order));

六、常见面试题

1. Promise 有哪几种状态?

pending、fulfilled、rejected。

2. Promise 解决了什么问题?

回调地狱,让异步代码可链式、可阅读、可维护。

3. then、catch、finally 的执行顺序?

  • 成功:then → finally
  • 失败:catch → finally
  • finally 一定执行

4. Promise.all 和 Promise.race 区别?

  • all:全部成功才成功
  • race:谁快返回谁

5. Promise 是异步还是同步?

Promise 本身是同步执行 的,then/catch/finally 是微任务异步。


七、总结

  1. Promise 是异步封装对象,解决回调地狱
  2. 状态:pending → fulfilled /rejected
  3. 核心写法:new Promise((resolve,reject)=>{})
  4. 链式:.then().catch().finally()
  5. 并行:Promise.all()、Promise.race()

Promise 是现代 JS 异步的基石,下一篇我们学习 async/await ------ Promise 的语法糖,让异步代码写得和同步一模一样。

相关推荐
何何____11 分钟前
TypeScript 函数类型兼容性
前端·javascript·typescript
雪芽蓝域zzs21 分钟前
json数据转化成interface属性
前端·javascript·json
鬼手点金1 小时前
ReAct 循环
linux·服务器·前端·javascript·react.js·前端框架
雪芽蓝域zzs1 小时前
Vue导入方法三种方式对比
前端·javascript·vue.js
VimorphTech3 小时前
React 任务轮询,为什么不能只写一个 setInterval?
javascript·typescript
lexiangqicheng3 小时前
Docker的沙箱机制是怎样的?
前端·javascript
LCG米5 小时前
STM32 HardFault故障定位实测:压栈帧寄存器解析、CFSR故障源判读与出错地址回溯
前端·javascript·stm32·单片机·嵌入式
持敬chijing5 小时前
白盒测试与代码审计-JS 数据逆向
javascript·网络·安全·web安全·网络安全·网络攻击模型·安全威胁分析
薛一半6 小时前
Redux实战:组件状态管理全解析
开发语言·前端·javascript·react.js