点击查看代码
先明确核心问题:为什么需要 Promise?—— 解决「异步操作」的 “等待 + 结果处理” 问题。
一、先搞懂:什么是 “异步操作”?
咱们先区分「同步」和「异步」,这是理解 Promise 的前提:
1. 同步操作(按顺序来,等上一个做完才做下一个)
比如:
console.log("第一步:烧水");
console.log("第二步:泡茶");
console.log("第三步:喝茶");
执行结果:先烧水 → 再泡茶 → 最后喝茶,一步不差。
2. 异步操作(不等上一个做完,直接做下一个)
比如:烧水需要等 1 分钟,代码里用 setTimeout 模拟 “等 1 分钟”:
console.log("第一步:开始烧水(需要等1分钟)");
setTimeout(() => {
console.log("水烧开了");
}, 1000);
console.log("第二步:准备泡茶");
执行结果:
第一步:开始烧水(需要等1分钟)
第二步:准备泡茶
水烧开了
问题出现了:我们想 “等水烧开再泡茶”,但代码没等,直接执行了 “准备泡茶”
这就是异步操作的痛点:异步操作的结果,没法用同步代码的方式 “等” 它完成。
再比如:前端调接口(网络请求)、读取本地文件、定时器,都是异步操作 —— 这些操作需要 “等结果”,但代码不会停。
而ajax就是异步的,所以需要promise来解决这个问题
二、Promise 到底是什么?(生活例子类比)
Promise 就像「外卖订单」:
你下单(创建 Promise)→ 订单状态是「待接单」(pending);
商家接单并做好配送(异步操作完成)→ 订单状态变成「已完成」(fulfilled),你拿到外卖(获取成功结果);
商家没货 / 配送失败(异步操作失败)→ 订单状态变成「已取消」(rejected),你收到失败原因(获取错误信息);
状态一旦变了(完成 / 取消),就再也改不了(比如订单完成了,不能再变回待接单)。
总结:Promise 是一个「管理异步操作的对象」,核心作用是:
记录异步操作的状态(进行中 / 成功 / 失败);
异步操作完成后,通知你处理结果(成功就用,失败就修)。
三、Promise 的基本语法(手把手教写)
const promise = new Promise((resolve, reject) => {
// 这里可以调用 resolve() 和 reject()
//resolve 和 reject 是从哪来的?resolve 和 reject 是 Promise 的构造函数提供给你的两个回调函数。
});
// 简化版 Promise 实现(帮助你理解)
class MyPromise {
constructor(executor) {
// 定义两个函数
const resolve = (value) => {
// 处理成功逻辑
this.status = 'fulfilled';
this.value = value;
};
const reject = (reason) => {
// 处理失败逻辑
this.status = 'rejected';
this.reason = reason;
};
// 关键!把这两个函数传给你的执行函数
try {
executor(resolve, reject); // 这里传入了 resolve 和 reject!
} catch (error) {
reject(error);
}
}
}
// 使用时
const promise = new MyPromise((resolve, reject) => {
// 看!resolve 和 reject 是 MyPromise 传给我们的
resolve('成功!');
});
示例:
1. 创建 Promise(下外卖订单)
语法结构:
// 1. 创建Promise实例(下单)
const 订单 = new Promise((resolve, reject) => {
// 2. 里面写异步操作(商家做餐+配送)
// 模拟异步操作:比如等1分钟做餐
setTimeout(() => {
const 有货 = true; // 模拟“有货/没货”
if (有货) {
// 3. 成功:调用resolve,状态变成“已完成”,传递结果(外卖)
resolve("你的奶茶到了!");
} else {
// 4. 失败:调用reject,状态变成“已失败”,传递原因(没货)
reject("抱歉,奶茶售罄了");
}
}, 1000);
});
核心参数解释:
resolve:函数 → 异步成功时调用,把 Promise 状态改成 fulfilled(已成功),并传结果,然后下面的.then就可以执行了;
reject:函数 → 异步失败时调用,把 Promise 状态改成 rejected(已失败),并传错误原因,然后下面的.catch就可以执行了;
注意:Promise 一旦创建,里面的异步操作会「立即执行」(就像下单后商家马上开始处理)。
2. 消费 Promise(处理订单结果)
创建了 Promise 后,需要用 .then()/.catch()/.finally() 处理结果(就像你处理外卖订单的结果):
// 处理订单结果
订单
.then((成功结果) => {
// 异步成功时执行(拿到外卖)
console.log("成功:", 成功结果); // 输出:成功:你的奶茶到了!
})
.catch((失败原因) => {
// 异步失败时执行(没拿到外卖)
console.error("失败:", 失败原因);
})
.finally(() => {
// 无论成功/失败,最终都会执行(比如不管有没有奶茶,都要擦桌子)
console.log("操作结束:不管有没有奶茶,都要收拾桌面");
});
解释:
.then():接收成功结果,异步成功就跑这里;
.catch():接收失败原因,异步失败就跑这里;
.finally():收尾操作,成功失败都跑这里(可选)。
3. 日常开发中,很多常用库 / API 都会返回 Promise,不用自己手动创建:
axios 所有请求方法:axios.get()/axios.post()/axios.put() 等,都返回 Promise;
fetch API(前端原生请求):fetch(url) 返回 Promise;
Node.js 异步 API:比如 fs.promises.readFile()(读取文件)返回 Promise;
自己封装的异步函数:比如之前讲的 点奶茶() 函数,我们手动 return 了 Promise。