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 的语法糖,让异步代码写得和同步一模一样

相关推荐
cn_mengbei5 小时前
用React Native开发OpenHarmony应用:Reanimated共享元素过渡
javascript·react native·react.js
kyriewen5 小时前
前端测试:别为了100%覆盖率而写测试,那是自欺欺人
前端·javascript·单元测试
Data_Journal5 小时前
如何使用cURL更改User Agent
大数据·服务器·前端·javascript·数据库
掌心向暖RPA自动化5 小时前
如何获取网页某个元素在屏幕可见部分的中心坐标影刀RPA懒加载坐标定位技巧
java·javascript·自动化·rpa·影刀rpa
竹林8185 小时前
wagmi v2 多链钱包切换:一个 Uniswap 仿盘项目让我踩了三天坑
前端·javascript
你也向往长安城吗6 小时前
最快的 JavaScript navmesh pathfinding3d 算法。
javascript
滕青山6 小时前
在线PDF拆分工具核心JS实现
前端·javascript·vue.js
兔子零10248 小时前
Ofox AI值得用吗?
前端·javascript·后端
We་ct8 小时前
React 性能优化精讲
前端·javascript·react.js·性能优化·前端框架·html·浏览器
渣渣盟9 小时前
Spark 性能调优实战:从开发到生产落地
javascript·ajax·spark