深度分析Javascript中的Promise
你提到的这段代码:
new Promise((resolve, reject) => {console.log(3);resolve(1000);console.log(4);
});
我将分成你要求的 2 大部分详细解释:Promise 是什么?参数和语法又是什么?
🧩 一、Promise 是什么?
✅ Promise 是 JavaScript 用来处理 异步操作 的对象。
它可以表示一个 当前还未完成、但将来会完成 的任务,避免了回调地狱(callback hell)。
它有三种状态:
-
pending
:初始状态,未完成 -
fulfilled
:任务成功完成(调用了resolve
) -
rejected
:任务失败(调用了reject
)
🧪 二、代码行为详解
new Promise((resolve, reject) => {console.log(3); // 👉 同步执行,立即输出resolve(1000); // 👉 将状态改为 fulfilled(成功)console.log(4); // 👉 同步执行,继续输出
});
这段代码的执行顺序为:
3
4
⚠️ 注意:
resolve(1000)
不会立刻打印出1000
,因为它是要搭配.then()
来获取值的。
例如:
new Promise((resolve, reject) => {console.log(3);resolve(1000);console.log(4);
}).then(value => {console.log('结果是:', value);
});
输出:
3
4
结果是: 1000
🔧 三、构造函数参数解释(重点)
new Promise((resolve, reject) => {// 执行器 executor 函数
});
这个传进去的函数叫做 执行器函数(executor function),它会在 new Promise(...)
这一刻 立刻被执行。
参数说明:
-
resolve(value)
:表示任务成功,传给.then()
的回调。 -
reject(error)
:表示任务失败,传给.catch()
的回调。
🔤 四、语法深度分析
1. (resolve, reject) => { ... }
是什么?
这是一个箭头函数(arrow function),是 ES6 中的新语法。
等价于:
function(resolve, reject) {// ...
}
所以你问的:
“形参里的方法是什么意思,是函数声明吗?”
答:它是一个函数表达式,不是函数声明,属于函数表达式的语法形式。
2. 属于语法的什么部分?
-
整个
new Promise(...)
是在调用构造函数(Promise 构造器)。 -
构造器中传入的是一个函数表达式。
-
resolve
和reject
是该函数的参数(由 Promise 引擎提供)。
🌱 五、扩展语法知识
✅ 几种函数写法对比
// 传统函数声明
function add(a, b) {return a + b;
}// 函数表达式
const add = function(a, b) {return a + b;
};// 箭头函数
const add = (a, b) => a + b;
想学习更多的箭头函数的方法可以看我的博客。
关于Javascript ES6箭头函数用法的分析,函数声明的几个方式-CSDN博客
✅ Promise 常见用法
new Promise((resolve, reject) => {setTimeout(() => {resolve("ok");}, 1000);
}).then(result => {console.log(result); // "ok"
}).catch(error => {console.error(error);
});
✅ 总结回顾
项目 | 内容说明 |
---|---|
Promise | 异步操作的封装对象,有状态转换 |
resolve/reject | 控制状态变为成功或失败 |
new Promise(...) | 构造器立即执行传入的函数 |
(resolve, reject) => {...} | 箭头函数语法,是一个函数表达式 |
如果你想深入学习 .then()
链式调用、错误处理 .catch()
、并发控制(如 Promise.all
, Promise.race
)等内容,我也可以帮你继续拓展。是否需要?
二、系统深入学习 Promise 的高级用法
下面我们来系统深入学习 Promise 的高级用法,涵盖:
-
.then()
链式调用 -
.catch()
错误处理 -
并发控制:
Promise.all()
、Promise.race()
、Promise.allSettled()
、Promise.any()
-
每个部分都附带【详细解释 + 案例 + 注释】
✅ 1. .then()
链式调用
🌟 基本语法
doSomething().then(result => doNext(result)).then(nextResult => doFinal(nextResult)).then(finalResult => {console.log('最终结果:', finalResult);});
✅ 原理:每个 .then()
都会返回一个新的 Promise。
📦 示例:处理异步步骤流程
function step1() {return new Promise(resolve => {setTimeout(() => resolve('🟢 Step 1 done'), 500);});
}function step2(prev) {return new Promise(resolve => {setTimeout(() => resolve(`${prev} → 🟡 Step 2 done`), 500);});
}function step3(prev) {return new Promise(resolve => {setTimeout(() => resolve(`${prev} → 🔵 Step 3 done`), 500);});
}step1().then(res => step2(res)) // 把结果传入 step2.then(res => step3(res)) // 把结果传入 step3.then(res => console.log('✅ 结果:', res));
🟨 输出(延迟后):
✅ 结果: 🟢 Step 1 done → 🟡 Step 2 done → 🔵 Step 3 done
❗ 2. .catch()
错误处理
📌 用于捕获前面 .then()
中的错误
doSomething().then(res => {throw new Error("出错啦!");}).catch(err => {console.error("捕获错误:", err.message);});
📦 示例:模拟网络失败
function fetchData() {return new Promise((resolve, reject) => {setTimeout(() => {reject(new Error('❌ 网络请求失败'));}, 300);});
}fetchData().then(res => console.log('✅ 请求成功:', res)).catch(err => console.error('❗ 捕获错误:', err.message));
🧵 3. 并发控制方法
🔸 3.1 Promise.all()
-
✅ 等所有 Promise 都成功后,才进入
.then()
-
❌ 有一个失败,就立即进入
.catch()
const p1 = Promise.resolve(1);
const p2 = Promise.resolve(2);
const p3 = Promise.resolve(3);Promise.all([p1, p2, p3]).then(results => {console.log('✅ 所有完成:', results); // [1, 2, 3]}).catch(err => {console.error('❌ 某个失败:', err);});
🔸 3.2 Promise.race()
-
✅ 谁先完成/失败,就返回谁
-
适用于:超时控制
const slow = new Promise(resolve => setTimeout(() => resolve('🐢 慢响应'), 2000));
const fast = new Promise(resolve => setTimeout(() => resolve('🐇 快响应'), 500));Promise.race([slow, fast]).then(result => {console.log('⚡ 先返回的:', result); // 🐇 快响应});
🔸 3.3 Promise.allSettled()
-
💡 等所有 Promise 都完成(无论成功或失败),返回每个状态和结果。
const p1 = Promise.resolve('✔ 成功1');
const p2 = Promise.reject('✖ 失败2');
const p3 = Promise.resolve('✔ 成功3');Promise.allSettled([p1, p2, p3]).then(results => {results.forEach((res, i) => {console.log(`任务 ${i + 1}:`, res.status, res.value || res.reason);});});
输出:
任务 1: fulfilled ✔ 成功1
任务 2: rejected ✖ 失败2
任务 3: fulfilled ✔ 成功3
🔸 3.4 Promise.any()
-
✅ 返回第一个成功的值
-
❌ 如果都失败,则报错
AggregateError
const p1 = Promise.reject('失败1');
const p2 = Promise.reject('失败2');
const p3 = Promise.resolve('成功3');Promise.any([p1, p2, p3]).then(result => {console.log('✅ 首个成功:', result); // 成功3}).catch(err => {console.error('全部失败:', err);});
📌 技巧拓展:模拟请求 + 超时处理
function fakeFetch(url, delay) {return new Promise(resolve => {setTimeout(() => resolve(`✅ 响应自 ${url}`), delay);});
}const request = fakeFetch('/api/data', 2000);
const timeout = new Promise((_, reject) =>setTimeout(() => reject(new Error('⏱ 请求超时')), 1000)
);Promise.race([request, timeout]).then(res => console.log(res)).catch(err => console.error(err.message));
输出:
⏱ 请求超时
✅ 总结对照表
方法 | 等待全部? | 返回什么? | 失败会怎样? |
---|---|---|---|
Promise.all | 是 | 所有结果 | 任一失败就失败 |
Promise.race | 否 | 最快那个的结果 | 最快失败就失败 |
Promise.allSettled | 是 | 所有状态和结果 | 不会失败 |
Promise.any | 否 | 第一个成功的值 | 全失败时才报错 |
如果你需要我帮你出一些练习题、面试题,或者你想手写模拟一个 Promise.all
的实现,我也可以继续带你深入。是否继续?