深入理解 Promise:规范与应用

一、引言

在 JavaScript 中,异步编程是核心能力之一。传统的回调函数虽然能解决问题,但随着业务逻辑复杂度增加,往往会陷入「回调地狱」。为了解决这个问题,Promise 应运而生,并逐渐成为前端开发的标配。本文将从 Promise 的规范、实现原理、常用方法、手写实现async/await 与面试题讲解,带你全面掌握 Promise。


二、Promises/A+ 规范

Promise 是一个状态机,它有三种状态:

  • pending:初始状态

  • fulfilled:操作成功

  • rejected:操作失败

特点:

  1. 状态一旦改变就不可逆。

  2. then 方法可接收两个回调函数,分别处理成功与失败。

  3. then 的链式调用遵循「值穿透」与「异常捕获」机制。


三、传统异步处理的问题

function request(cb) {
  setTimeout(() => {
    let flag = Math.random() > 0.5;
    cb(flag, flag ? "成功的数据" : "失败的数据");
  }, 1000);
}

request((status, msg) => {
  if (status) {
    console.log("成功", msg);
  } else {
    console.log("失败", msg);
  }
});

随着业务嵌套过多,容易导致 回调地狱,难以维护与扩展。


四、Promise 的基本使用

Promise 是一个类,需通过 new 实例化:

const request = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      Math.random() > 0.5 ? resolve("成功") : reject("失败");
    }, 1000);
  });
};

request()
  .then(res => console.log("结果:", res))
  .catch(err => console.log("错误:", err))
  .finally(() => console.log("请求结束"));

五、Promise 的常用方法

  1. then / catch / finally
    链式调用,支持异常捕获。

  2. Promise.resolve / Promise.reject
    快速创建成功/失败的 Promise。

  3. Promise.all
    等待所有任务完成,若有一个失败则整体失败。

  4. Promise.allSettled
    等所有任务完成后返回每个任务的状态与结果。

  5. Promise.race
    谁先完成就返回谁的结果。

  6. Promise.any
    等第一个成功的任务返回,若全部失败才返回错误。


六、手写 Promise(简化版思路)

class MyPromise {
  constructor(executor) {
    this.state = "pending";
    this.value = null;
    this.callbacks = [];

    const resolve = (value) => {
      if (this.state === "pending") {
        this.state = "fulfilled";
        this.value = value;
        this.callbacks.forEach(cb => cb.onFulfilled(value));
      }
    };

    const reject = (reason) => {
      if (this.state === "pending") {
        this.state = "rejected";
        this.value = reason;
        this.callbacks.forEach(cb => cb.onRejected(reason));
      }
    };

    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      if (this.state === "fulfilled") {
        resolve(onFulfilled(this.value));
      } else if (this.state === "rejected") {
        reject(onRejected(this.value));
      } else {
        this.callbacks.push({ onFulfilled, onRejected });
      }
    });
  }
}

七、async / await 的语法糖

async/await 是基于 Promise 的进一步封装,写法更接近同步:

async function fetchData() {
  try {
    let res = await request();
    console.log("结果:", res);
  } catch (err) {
    console.log("错误:", err);
  } finally {
    console.log("请求结束");
  }
}

八、面试高频题目

例题 1

const promise = new Promise((resolve, reject) => {
  console.log(1);
  console.log(2);
});
promise.then(() => {
  console.log(3);
});
console.log(4);

// 输出:1 2 4

例题 2

Promise.resolve()
  .then(() => {
    console.log("promise1");
    setTimeout(() => console.log("timer2"), 0);
  });
setTimeout(() => {
  console.log("timer1");
  Promise.resolve().then(() => console.log("promise2"));
}, 0);
console.log("start");

// 输出: start → promise1 → timer1 → promise2 → timer2

更多题目可结合 事件循环(宏任务/微任务) 深入分析。


九、总结

  • Promise 的本质是 异步编程的一种解决方案,核心在于状态管理与链式调用。

  • 熟练掌握 常用 API,并理解 事件循环,是面试与实战的关键。

  • async/await 让代码更简洁,但底层仍然依赖 Promise。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wen's

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值