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

相关推荐
带娃的IT创业者2 小时前
TTS静默之谜:pyttsx3 全局缓存陷阱与qasync环境四轮诊断实战
缓存·tts·异步编程·pyttsx3·qasync·windows sapi5·com 线程模型
zhensherlock2 小时前
Protocol Launcher 系列:Trae AI 编辑器的深度集成
javascript·人工智能·vscode·ai·typescript·编辑器·ai编程
吠品3 小时前
Vue项目Moment.js引入优化:全局挂载与按需引入的深度解析与最佳实践
前端·javascript·vue.js
不甜情歌3 小时前
JS 类型判断不用愁:4 种方法,覆盖所有场景
前端·javascript
共享家95273 小时前
单例模式( 饿汉式与懒汉式 )
开发语言·javascript·ecmascript
cmd3 小时前
前端基础必看:JS 变量提升 & 函数提升完整解析
前端·javascript
小金鱼Y3 小时前
前端必看:this 不是玄学!5 大绑定规则帮你永久告别 this 困惑
前端·javascript·面试
yusheng_xyb3 小时前
使用TypeScript与React构建高效用户界面
typescript·react·前端开发