一、基本框架实现
实现以下结构的promise自定义封装
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('oK');
}, 1000);
})
.then((value) => {
console.log(value);
})
.catch((reason) => {
console.log(reason);
});
</script>
步骤:
1. 初始结构状态搭建
2. resolve与reject结构搭建
3. throw抛出异常状态改变
4. promise对象状态只修改一次
5. then方法执行回调
<script>
//1.构造函数
function Promise(executor){
//添加属性
//设置初始状态
this.Promisestate ='pending'
//设置初始值
this.PromiseResult = null
//保存实例对象的this值
const self = this
//2. resolve与reject结构搭建
function resolve(data){
//判断 4. promise对象状态只修改一次
if(self.PromiseState !== 'pending')return
//(1)修改对象状态(Promisestate)
self.Promisestate='fulfilled'//resolved 解决
//(2)设置对象结果值(PromiseResult)
self.PromiseResult = data
}
function reject(data){
//判断 4. promise对象状态只修改一次
if(self.PromiseState !== 'pending')return
//(1)修改对象状态(Promisestate)
self.PromiseState="rejected"
//(2)设置对象结果值(PromiseResult)
self.PromiseResult=data
}
//3. throw抛出异常状态改变
try {
//同步调用[执行器函数]
executor(resolve,reject)
}catch(e){
//修改promise对象状态为失败
reject(e)
}
}
//5.添加then方法 (then方法执行回调)
Promise.prototype.then=function(onResolve, onReject){
//调用回调函数 Promisestate
if(this.PromiseState ==='fulfilled'){
onResolve(this.PromiseResult)
}
if(this.PromiseState ==='rejected'){
onReject(this.PromiseResult)
}
}
</script>
6.同步异步回调处理时机
1. 同步修改状态(状态已确定)
if (this.PromiseState === 'fulfilled') {
onResolve(this.PromiseResult) // 直接调用成功回调
}
if (this.PromiseState === 'rejected') {
onReject(this.PromiseResult) // 直接调用失败回调
}
-
原因:
当then被调用时,Promise 的状态已经同步确定(例如在构造函数中直接调用了resolve/reject)。 -
行为:
可以立即使用已知的PromiseResult调用对应的回调函数(onResolve或onReject)。 -
示例:
const p = new MyPromise((resolve) => resolve(123)) p.then(res => console.log(res)) // 同步执行,立即输出 123
2. 异步修改状态(状态未确定)
if (this.PromiseState === 'pending') {
this.callbacks.push({ // 保存回调到数组
onResolve: () => onResolve(this.PromiseResult),
onReject: () => onReject(this.PromiseResult)
})
}
-
原因:
当then被调用时,Promise 的状态尚未确定(例如resolve/reject在setTimeout中异步调用)。 -
行为:
无法立即执行回调,必须先将回调函数保存起来,等待未来状态确定后再触发。 -
示例:
const p = new MyPromise((resolve) => { setTimeout(() => resolve(123), 1000) }) p.then(res => console.log(res)) // 1秒后异步执行
关键区别:回调的执行时机
| 场景 | 状态时机 | then 的行为 | 必要性 |
|---|---|---|---|
| 同步修改 | 调用 then 前已确定 | 立即执行回调 | 结果立即可用 |
| 异步修改 | 调用 then 时未确定 | 保存回调,延迟执行 | 结果未来才可用 |
举个例子:
- 同步
const p = new Promise((resolve, reject) => {
resolve('success'); // 同步调用 resolve
});
p.then(
value => console.log(value), // onResolve
reason => console.error(reason) // onReject
);
阶段1:同步代码执行(调用栈)
-
创建 Promise 实例
p-
同步执行 executor 函数
(resolve, reject) => { ... } -
立即调用
resolve('success') -
此时 Promise 内部状态变为:
{ PromiseState: 'fulfilled', PromiseResult: 'success' }
-
-
调用
p.then()方法-
检查
p的状态已经是fulfilled -
将
onResolve回调(value => console.log(value))放入微任务队列 -
此时微任务队列内容:
[微任务1: console.log('success')]
-
阶段2:微任务执行(当前宏任务结束后)
-
事件循环处理微任务队列
- 从微任务队列中取出并执行
onResolve回调 - 执行
console.log('success') - 控制台输出:
success
- 从微任务队列中取出并执行
-
微任务队列清空
- 所有微任务执行完毕,程序结束
关键机制说明
-
Promise 状态变化是同步的
resolve('success'); // 同步修改状态- 此操作会立即将 Promise 从
pending变为fulfilled - 但回调函数(
.then)的执行永远是异步的(即使状态已确定)
- 此操作会立即将 Promise 从
-
.then()的回调调度规则-
如果 Promise 已经是
fulfilled/rejected:- 将对应的回调(
onResolve或onReject)放入微任务队列
- 将对应的回调(
-
如果 Promise 还是
pending:- 将回调暂存,待状态变化后再调度
-
- 异步
const p = new Promise((resolve, reject) => {
setTimeout(() => resolve('success'), 1000)
})
p.then(
value => console.log(value), // onResolve
reason => console.error(reason) // onReject
)
二、异步任务回调的执行
setTimeout模拟异步任务回调
<script>
const p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('oK');
}, 1000);
})
.then((value) => {
console.log(value);
})
.catch((reason) => {
console.log(reason);
});
</script>
- 在状态改变之前先保存回调函数,注意先声明callback属性
this.callback={}
//添加then方法 (then方法执行回调)
Promise.prototype.then=function(onResolve, onReject){
//调用回调函数 Promisestate
if(this.PromiseState ==='fulfilled'){
onResolve(this.PromiseResult)
}
if(this.PromiseState ==='rejected'){
onReject(this.PromiseResult)
}
// 在状态改变之前先保存回调函数,注意先声明callback属性
if (this.PromiseState === 'pending') {
this.callback = {
onResolve: onResolve,
onReject: onReject
},
}
- 调用成功/失败时的回调函数
//声明属性
this.callback = {}
//resolve函数
function resolve(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'fulfilled'//resolved 解决
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用成功的回调函数
//如果self.callback里面有onResolve
if (self.callback.onResolve) {
self.callback.onResolve(data)
}
}
//reject函数
function reject(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'rejected'
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用失败的回调函数
//如果self.callback里面有onRejected
if (self.callback.onReject) {
self.callback.onReject(data)
}
}
三、指定多个回调的实现
//异步任务回调执行
const p =new Promise((resolve, reject)=>{
setTimeout(()=>{resolve('ok')},1000)
// reject('err')
// throw('err')
})
//指定多个回调
p.then((value)=>{
console.log(value)
},(reason)=>{
console.warn(reason)
})
p.then((value)=>{
alert(value)
},(reason)=>{
alert(reason)
})
指定多个回调,this.callback = { onResolve: onResolve, onReject: onReject }这种写法就会使后面的对象覆盖前面的,只会执行alert;

解决办法,把多个回调函数存在数组里;
// 构造函数中初始化数组
this.callbacks = [];
// then方法中
this.callbacks.push({
onResolve: onResolve,
onReject: onReject
});
1. 为什么 this.callback = { ... } 是错误的?
this.callback = {
onResolve: onResolve,
onReject: onReject
}
-
问题:每次调用
.then()都会覆盖之前的回调。
例如:promise.then(callback1); promise.then(callback2); // 覆盖 callback1,只保留 callback2 -
后果:当 Promise 状态变为
fulfilled/rejected时,只有最后一次设置的回调会被执行,违反了 Promise/A+ 规范(要求保留所有回调)。
2. 为什么 this.callbacks.push({ ... }) 是正确的?
// 构造函数中初始化数组
this.callbacks = [];
// then方法中
this.callbacks.push({
onResolve: onResolve,
onReject: onReject
});
-
原因:
- 同一个 Promise 可能多次调用
.then()(如promise.then(f1); promise.then(f2);)。 - 需要用数组存储所有回调,确保后续状态变化时按顺序执行所有回调。
- 符合 Promise/A+ 规范(2.2.6:
then可能被多次调用,需按注册顺序执行回调)。
- 同一个 Promise 可能多次调用
修改callback定义,且利用forEach遍历数组对象
按顺序执行所有回调
//声明属性
this.callback = {}
//resolve函数
function resolve(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'fulfilled'//resolved 解决
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用成功的回调函数
//如果self.callback里面有onResolve
// if (self.callback.onResolve) {
// self.callback.onResolve(data)
// }
setTimeout(() => {
self.callback.forEach(item => {
item.onResolve(data)
})
})
}
//reject函数
function reject(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'rejected'
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用失败的回调函数
//如果self.callback里面有onReject
// if (self.callback.onReject) {
// self.callback.onReject(data)
// }
setTimeout(() => {
self.callback.forEach(item => {
item.onReject(data)
})
})
}

四、同步修改状态then方法结果返回

结果:

(因为上述回调函数没有加return,所以PromiseResult为undifined)
同理reject状态执行结果:
关键:如果.then后面的函数返回的是非promise状态的函数,比如undifine,字符串等,状态都是resolve状态的;如果返回的是promise状态的,这个返回的promise状态就决定了.then结果的状态
实现源码:
//添加then方法 (then方法执行回调)
Promise.prototype.then=function(onResolve, onReject){
//调用回调函数 Promisestate
if(this.PromiseState ==='fulfilled'){
onResolve(this.PromiseResult)
}
if(this.PromiseState ==='rejected'){
onReject(this.PromiseResult)
}
// 在状态改变之前先保存回调函数,注意先声明callback属性
if (this.PromiseState === 'pending') {
this.callback.push({
onResolve: onResolve,
onReject: onReject
}),
}
then方法返回结果:
- 非promise对象的reslove;
- promise对象的resolve和reject;
- 抛出异常情况下,改变状态为失败的reject;

抛出异常情况

五、异步修改状态then方法结果返回


此时状态还是pending,但是这里正确的Promise的then方法返回的应该是

修改异步情况下then返回的状态结果在PromiseState===pending时
同时,onReject执行过程同理:
then方法返回结果:
- 非promise对象的reslove;
- promise对象的resolve和reject;
- 抛出异常情况下,改变状态为失败的reject;
代码优化
疑惑点
异步场景执行流程(状态为 pending)
- 初始化阶段
const p = new Promise((resolve) => {
setTimeout(() => resolve('success'), 1000); // 异步 resolve
});
p.then(value => console.log(value)); // 调用 then 时状态为 pending
2. .then() 方法执行(状态为 pending)
Promise.prototype.then = function (onResolve, onReject) {
// ...
if (this.PromiseState === 'pending') {
// ✅ 进入此分支
this.callback.push({
onResolve: function () { callback(onResolve) },
onReject: function () { callback(onReject) }
})
}
}
- 将回调包装后存入
this.callback数组 - 不执行任何回调,直接返回新 Promise
- 异步操作完成后调用
resolve('success')
function resolve(data) {
// ...
self.PromiseState = 'fulfilled'
self.PromiseResult = data
setTimeout(() => { // ✅ 关键执行点
self.callback.forEach(item => {
item.onResolve(data) // 执行之前存储的回调
})
})
}
- 触发回调执行:通过
setTimeout调度 - 遍历存储的回调:执行每个
item.onResolve(data)
- 执行回调链
当 item.onResolve(data) 执行时:
// 实际执行的是 .then() 中存储的:
function() { callback(onResolve) }
// 展开 callback 函数:
function callback(type) {
try {
let result = type(self.PromiseResult) // 执行用户回调 value => console.log(value)
// 处理返回值,决定链式调用的状态...
} catch (e) {
reject(e)
}
}
所以在异步执行回调的场景中,当 .then() 被调用时 Promise 状态为 pending,执行的是 resolve 函数中的 setTimeout 回调,而不是 .then() 方法中的 if (this.PromiseState === 'fulfilled') 分支。
六、catch方法-异常穿透和值传递

异常穿透
异常穿透是 Promise 链式调用中的一个重要特性,它允许错误沿着 Promise 链自动向后传递,直到被捕获处理。
实现异常穿透的关键代码
// 实现异常穿透的关键:提供默认错误处理
const defaultOnReject = reason => {
throw reason; // 抛出错误,使新 Promise 变为 rejected
};
onReject = typeof onReject === 'function'
? onReject
: defaultOnReject;
// 处理 onResolve 的默认行为
onResolve = typeof onResolve === 'function'
? onResolve
: value => value;
异常穿透的工作原理
- 默认错误处理行为
异常穿透的核心在于 then 方法的错误处理参数 onReject 的默认行为:
const defaultOnReject = reason => {
throw reason; // 关键:重新抛出错误
};
当用户没有提供 onReject 处理函数时,我们使用这个默认函数。这个函数简单地重新抛出接收到的错误原因,使新创建的 Promise 状态变为 rejected,并将错误继续传递下去。
- 同步错误捕获
try {
const result = callback(value);
// ...处理结果
} catch (error) {
reject(error); // 将同步错误转换为 Promise 拒绝
}
这样即使回调函数中抛出同步错误,也会被捕获并转换为 Promise 的拒绝状态,继续在链中传递。
异常穿透示例
// 创建初始 rejected Promise
const p = new MyPromise((resolve, reject) => {
reject('Initial error');
});
p.then(result => {
// 不会执行,因为初始状态是 rejected
console.log('Success:', result);
})
.then(() => {
// 没有提供错误处理,错误继续传递
console.log('This will not execute');
})
.catch(error => {
// 捕获到穿透传递的错误
console.log('Caught error:', error); // 输出: Caught error: Initial error
return 'Recovered';
})
.then(result => {
// 恢复执行
console.log('Recovery result:', result); // 输出: Recovery result: Recovered
});
值传递及错误捕获

执行过程分析
阶段1:同步代码执行(立即执行)
-
创建 Promise 对象
p,立即执行 executor 函数:- 设置一个定时器(1秒后触发
resolve('ok')) - 注意:
reject('err')和throw('fail')被注释掉了 - 此时 Promise 状态为
pending
- 设置一个定时器(1秒后触发
-
链式调用
.then()和.catch():-
由于 Promise 还是
pending状态,所有回调都被暂存到微任务队列 -
此时回调队列情况:
微任务队列: [then1, then2, then3, catch]
-
阶段2:异步任务执行(1秒后)
-
1秒后定时器触发,执行
resolve('ok'):-
Promise 状态从
pending变为fulfilled,结果为'ok' -
触发:将第一个
.then()的回调放入微任务队列 -
此时微任务队列:
[then1的回调, then2, then3, catch]
-
-
事件循环开始处理微任务队列:
-
执行第一个
.then()的回调:console.log(111) // 输出: 111-
回调没有返回值,相当于返回
undefined -
创建一个新的 fulfilled 状态的 Promise,值为
undefined -
触发:将第二个
.then()的回调放入微任务队列 -
微任务队列:
[then2的回调, then3, catch]
-
-
执行第二个
.then()的回调:console.log(222) // 输出: 222-
同样返回
undefined -
创建新的 fulfilled Promise
-
触发:将第三个
.then()的回调放入微任务队列 -
微任务队列:
[then3的回调, catch]
-
-
执行第三个
.then()的回调:console.log(333) // 输出: 333- 返回
undefined - 创建新的 fulfilled Promise
.catch()不会被调用,因为前面没有 rejection
- 返回
-
最终输出顺序
111
222
333
关键点说明
-
执行顺序:
- 所有
.then()注册时都是同步执行的 - 实际回调要等到 Promise 状态确定后才执行
- 所有
-
错误情况对比:
-
如果使用
reject('err'):- 输出:
err(catch 捕获) - 不会执行任何
.then()
- 输出:
-
如果使用
throw('fail'):- 同步抛出异常,Promise 直接变为 rejected
- 输出:
fail(catch 捕获)
-
1.异常穿透
场景:
const p = new Promise((resolve, reject) => {
setTimeout(() => { reject('err') }, 1000)
// resolve('ok')
// throw('fail')
})
p.then(value => { console.log(111) })
.then(value => { console.log(222) })
.then(value => { console.log(333) })
.catch(reason => { console.warn(reason) })
封装:
Promise.prototype.then=function(onResolve, onReject){
const self=this
if (typeof onReject !== 'function') {
onReject = reason => { throw reason } // 关键点:重新抛出错误
}
if (typeof onResolve !== 'function') {
onResolve = value => value // 值穿透:直接传递值
}
}
代码解析:
if (typeof onReject !== 'function') {
onReject = reason => { throw reason }
}
-
检查是否提供了错误处理函数
onReject -
如果没有提供(即
onReject不是函数类型):- 创建一个默认的错误处理函数
- 该函数会重新抛出接收到的错误原因
作用:实现异常穿透
Promise.reject('error')
.then() // 没有提供错误处理
.then() // 没有提供错误处理
.catch(console.log) // 最终被捕获
// 输出: 'error'
执行流程:
- 初始 Promise 被拒绝
- 第一个
.then()没有错误处理 → 执行默认函数throw reason - 导致返回的新 Promise 也被拒绝(携带相同错误)
- 错误继续向下传递,直到被
.catch()捕获
2.值传递
场景:
const p = new Promise((resolve, reject) => {
setTimeout(() => { resolve('ok') }, 1000)
// reject('err')
// throw('fail')
})
p.then(value => { console.log(111) })
.then(value => { console.log(222) })
.then(value => { console.log(333) })
.catch(reason => { console.warn(reason) })
封装:
Promise.prototype.then=function(onResolve, onReject){
const self=this
if (typeof onReject !== 'function') {
onReject = reason => { throw reason } // 关键点:重新抛出错误
}
if (typeof onResolve !== 'function') {
onResolve = value => value // 值穿透:直接传递值
}
}
代码解析
if (typeof onResolve !== 'function') {
onResolve = value => value
}
-
检查是否提供了成功回调
onResolve -
如果没有提供(即
onResolve不是函数类型):- 创建一个默认的成功处理函数
- 该函数会直接返回接收到的值
作用:实现值穿透
Promise.resolve('success')
.then() // 没有提供成功回调
.then(value => console.log(value))
// 输出: 'success'
执行流程:
- 初始 Promise 成功解决
- 第一个
.then()没有成功回调 → 执行默认函数value => value - 返回的新 Promise 以相同值解决
- 值传递给下一个
.then()被处理
| 特性 | 条件判断 | 默认行为 | 作用 |
|---|---|---|---|
| 异常穿透 | typeof onReject !== 'function' | reason => { throw reason } | 错误沿 Promise 链向下传递 |
| 值穿透 | typeof onResolve !== 'function' | value => value | 值沿 Promise 链向下传递 |
七、Promise.resolve封装
1.基本概念
Promise.resolve()是 Promise 的一个静态方法,用于创建一个已解决(fulfilled)状态的 Promise 对象。
语法
Promise.resolve(value);
参数
-
value:可以是任何 JavaScript 值,包括:- 普通值(数字、字符串、对象等)
- Promise 对象
- thenable 对象(具有
then方法的对象)
返回值
返回一个 Promise 对象,其状态取决于传入的 value 参数:
- 如果参数是普通值,返回 fulfilled 状态的 Promise
- 如果参数是 Promise 对象,直接返回该 Promise
- 如果参数是 thenable 对象,返回的 Promise 会"跟随"这个 thenable 对象
具体场景分析
- 场景1:参数是非Promise值
Promise.resolve(42)
执行流程:
- 检查
42不是 Promise 实例 - 直接调用
resolve(42) - 返回的 Promise 立即变为 fulfilled 状态,值为 42
- 场景2:参数是已解决的Promise
const p = Promise.resolve('hello')
Promise.resolve(p)
执行流程:
- 检测到
p是 Promise 实例 - 调用
p.then()等待其解决 - 当
p解决后,用相同结果解决新 Promise
- 场景3:参数是拒绝的Promise
const p = Promise.reject('error')
Promise.resolve(p).catch(console.log) // 会捕获到'error'
执行流程:
- 检测到
p是 Promise 实例 - 调用
p.then()等待其解决 - 当
p拒绝后,用相同原因拒绝新 Promise
与 new Promise() 的区别
| 特性 | Promise.resolve() | new Promise() |
|---|---|---|
| 创建方式 | 静态方法 | 构造函数 |
| 初始状态 | 总是已解决 | pending |
| 输入类型处理 | 智能处理各种类型 | 只接受执行器函数 |
| 性能 | 更高效(无额外包装) | 稍低效 |
Promise.resolve('直接解析')和Promise.resolve('直接解析').then(...)
| 特性 | Promise.resolve('直接解析') | Promise.resolve('直接解析').then(...) |
|---|---|---|
| 返回值 | 直接返回一个 fulfilled 状态的 Promise | 返回一个新的 pending 状态的 Promise |
| 执行时机 | 同步创建 Promise(立即完成) | 回调函数异步执行(进入微任务队列) |
| 链式调用 | 仅创建 Promise,不触发回调 | 创建 Promise 并注册回调,形成链式调用 |
| 控制台输出 | 无输出 | 异步输出 '直接解析' |
示例1:基础行为
// 情况1:仅创建 Promise
const p1 = Promise.resolve('直接解析');
// p1 状态立即变为 fulfilled,但无任何输出
// 情况2:创建 Promise 并链式调用
const p2 = Promise.resolve('直接解析').then(val => console.log(val));
// p2 是 pending 状态,回调进入微任务队列
// 后续会输出: '直接解析'
示例2:执行顺序验证
console.log('开始');
Promise.resolve('直接解析'); // 同步创建,无输出
Promise.resolve('链式解析').then(val => console.log(val)); // 回调进入微任务队列
console.log('结束');
// 输出顺序:
// 开始
// 结束
// 链式解析
3. 关键差异解析
(1) 执行机制
-
Promise.resolve('直接解析')- 同步创建一个状态为
fulfilled的 Promise,值为'直接解析' - 不涉及异步逻辑,不会触发任何回调。
- 同步创建一个状态为
-
.then(val => console.log(val))- 在前一个 Promise 的基础上注册回调
- 回调函数会被异步执行(放入微任务队列)
- 返回一个新的 Promise 对象(初始状态为
pending)
(2) 返回值状态
const a = Promise.resolve('A');
console.log(a); // Promise {<fulfilled>: 'A'} (立即完成)
const b = Promise.resolve('B').then(val => console.log(val));
console.log(b); // Promise {<pending>} (等待回调执行)
(3) 链式调用的必要性
- 如果只需要存储值而不处理,用
Promise.resolve()即可 - 如果需要处理值或确保异步执行,必须加
.then()
示例3:执行顺序验证
console.log('start');
Promise.resolve('直接解析').then(val => console.log(val));
Promise.resolve().then(() => console.log('通过 then 解析'));
console.log('end');
// 输出顺序:
// start
// end
// 直接解析
// 通过 then 解析
阶段1:同步代码执行(调用栈)
-
执行
console.log('start')- 立即输出:
start
- 立即输出:
-
执行
Promise.resolve('直接解析')- 同步创建一个状态为
fulfilled的 Promise,值为'直接解析' - 将
.then(val => console.log(val))的回调放入微任务队列 - 当前微任务队列:
[回调1]
- 同步创建一个状态为
-
执行
Promise.resolve()- 同步创建一个状态为
fulfilled的 Promise,值为undefined - 将
.then(() => console.log('通过 then 解析'))的回调放入微任务队列 - 当前微任务队列:
[回调1, 回调2]
- 同步创建一个状态为
-
执行
console.log('end')- 立即输出:
end
- 立即输出:
阶段2:微任务执行(当前宏任务结束后)
-
清空微任务队列(按照先进先出顺序):
-
执行回调1:
val => console.log(val)- 输出:
直接解析
- 输出:
-
执行回调2:
() => console.log('通过 then 解析')- 输出:
通过 then 解析
- 输出:
-
示例4:变体思考
console.log('start');
Promise.resolve().then(() => console.log('通过 then 解析'));
Promise.resolve('直接解析').then(val => console.log(val));
console.log('end');
// 输出顺序:
// start
// end
// 通过 then 解析
// 直接解析
2.封装源码:
(返回的是promise的对象,返回的状态决定Promise.resolve去执行什么状态;返回的是成功,Promise.resolve就是去执行成功,返回的是失败,Promise.resolve就是去执行失败,返回的是非promise对象。就设置状态为成功)
八、Promise.reject封装
1.基本概念
Promise.reject()是 Promise 的一个静态方法,用于快速创建一个已拒绝(rejected)状态的 Promise 对象。
示例1:基本使用
const p = Promise.reject(new Error('Something went wrong'));
p.catch(error => {
console.error(error.message); // 输出: "Something went wrong"
});
示例2:非错误对象作为原因
Promise.reject('plain string reason')
.catch(reason => {
console.log(reason); // 输出: "plain string reason"
});
与 Promise.resolve() 的区别
| 特性 | Promise.reject() | Promise.resolve() |
|---|---|---|
| 初始状态 | 立即创建 rejected 状态的 Promise | 立即创建 fulfilled 状态的 Promise |
| 参数处理 | 直接作为拒绝原因 | 会展开 thenable 对象 |
| 是否展开 thenable | 不会展开 thenable 对象 | 会展开 thenable 对象 |
const thenable = {
then(resolve, reject) {
resolve('resolved value');
}
};
// Promise.resolve 会展开 thenable
Promise.resolve(thenable)
.then(val => console.log(val)); // 输出: "resolved value"
// Promise.reject 不会展开 thenable
Promise.reject(thenable)
.catch(val => console.log(val === thenable)); // 输出: true
链式调用中的行为
Promise.reject('first error')
.then(() => {
console.log('This will never run');
})
.catch(err => {
console.log('Caught:', err); // 输出: "Caught: first error"
return 'recovery value';
})
.then(val => {
console.log('After recovery:', val); // 输出: "After recovery: recovery value"
});
2.封装源码
Promise.reject与Promise.resolve的不同就是,不管传什么参数,都是执行reject

九、Promise.all封装--全部成功
all 相当于是 & 关系

如果有一个失败就是返回失败的那一个的状态

优化版:
十、Promise.race封装--竞速
Promise.race的结果由数组中第一个改变的状态的promise决定

优化版
十一、Promise.any封装 -- 任意成功
- 成功条件:任意一个 Promise 成功
- 失败条件:所有 Promise 都失败
- 返回值:第一个成功的值 或 AggregateError
对比总结
| 特性 | Promise.all() | Promise.race() | Promise.any() |
|---|---|---|---|
| 成功条件 | 所有成功 | 第一个完成(无论成败) | 任意一个成功 |
| 失败条件 | 任意一个失败 | 无特定条件 | 所有失败 |
| 返回值 | 结果数组(按顺序) | 第一个完成的值 | 第一个成功的值 |
| 空输入 | 解决(空数组) | 永久pending | 拒绝(AggregateError) |
| 错误处理 | 返回第一个错误 | 返回第一个完成的结果 | 返回所有错误 |
| 适用场景 | 并行操作,全部成功执行 | 超时控制,竞速 | 冗余备份,任意成功 |
十二、Promise.allSettled封装--等待所有结果
- 不短路:等待所有 Promise 完成(无论成功/失败)
- 完整结果:返回每个 Promise 的最终状态和值
- 状态无关:永远不会 reject
// 添加 allSettled 方法
Promise.allSettled = function(promises) {
// 空数组特殊处理
if (promises.length === 0) {
return Promise.resolve([]);
}
return new Promise((resolve) => {
const results = new Array(promises.length);
let completed = 0;
// 使用 for 循环代替 forEach
for (let i = 0; i < promises.length; i++) {
// 确保处理的是 Promise 对象
Promise.resolve(promises[i])
.then(value => {
results[i] = { status: 'fulfilled', value };
})
.catch(reason => {
results[i] = { status: 'rejected', reason };
})
.finally(() => {
completed++;
// 检查是否所有 Promise 都已完成
if (completed === promises.length) {
resolve(results);
}
});
}
});
};
十三、Promise.withResolvers -- 分离控制权
- 控制权分离:将 Promise 的 resolve/reject 与 Promise 本身分离
- 外部控制:可以在 Promise 外部控制其状态
// 添加 withResolvers 方法
Promise.withResolvers = function() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
};
总结:
allSettled()解决完整结果收集问题withResolvers()解决外部控制问题
十四、then方法回调的异步执行
用setTimeout模拟异步延迟回调


源码
//声明构造函数
function Promise(executor) {
//添加属性
//设置初始状态
this.PromiseState = 'pending'//初始状态
//设置初始值
this.PromiseResult = null
//声明属性
this.callback = []
//保存实例对象的this值
const self = this
//resolve函数
function resolve(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'fulfilled'//resolved 解决
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用成功的回调函数
//如果self.callback里面有onResolve
// if (self.callback.onResolve) {
// self.callback.onResolve(data)
// }
setTimeout(() => {
self.callback.forEach(item => {
item.onResolve(data)
})
})
}
//reject函数
function reject(data) {
//判断
if (self.PromiseState !== 'pending') return
//1.修改对象状态(PromiseState)
self.PromiseState = 'rejected'
//2.设置对象结果值(PromiseResult)
self.PromiseResult = data
//调用失败的回调函数
//如果self.callback里面有onReject
// if (self.callback.onReject) {
// self.callback.onReject(data)
// }
setTimeout(() => {
self.callback.forEach(item => {
item.onReject(data)
})
})
}
try {
//同步调用[执行器函数]
executor(resolve, reject)
} catch (e) {
//修改promise对象状态为失败
reject(e)
}
}
//添加then方法
Promise.prototype.then = function (onResolve, onReject) {
const self = this
//判断回调函数的参数
if (typeof onReject !== 'function') {
onReject = reason => {
throw reason
}
}
//值传递 第一个不传 就给它赋默认值
if (typeof onResolve !== 'function') {
onResolve = value => value
}
return new Promise((resolve, reject) => {
//封装函数
function callback(type) {
try {
let result = type(self.PromiseResult)
//判断
if (result instanceof Promise) {
//如果是promise类型对象
result.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
//如果是非promise类型对象
//结果状态为成功
resolve(result)
}
} catch (e) {
reject(e)
}
}
//调用回调函数 PromiseState
if ( self.PromiseState === 'fulfilled') {
setTimeout(() => { callback(onResolve) })
}
if ( self.PromiseState === 'rejected') {
setTimeout(() => { callback(onReject) })
}
// (异步)回调执行时机:在改变对象状态之后才执行的回调函数
if ( self.PromiseState === 'pending') {
//保存回调函数
self.callback.push({
onResolve: function () {
callback(onResolve)
},
onReject: function () {
callback(onReject)
},
})
}
})
}
//添加catch方法
Promise.prototype.catch = function (onRejected) {
//说明: then()的语法糖, 相当于: then(undefined, onRejected)
return this.then(undefined, onRejected)
}
//添加resolve方法
Promise.resolve = function (value) {
//返回Promise对象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(v => {
resolve(v)
}, r => {
reject(r)
})
} else {
//状态设置为成功
resolve(value)
}
})
}
//添加reject方法
Promise.reject = function (reason) {
return new Promise((_, reject) => {
reject(reason)
})
}
//添加all方法
Promise.all = function (promises) {
//返回结果为promise对象
return new Promise((resolve, reject) => {
let count = 0
let arr = []
if (promises.length === 0) {
resolve(arr);
return;
}
//遍历
for (let i = 0; i < promises.length; i++) {
// 确保处理的是 Promise 对象
Promise.resolve(promises[i]).then(v => {
//得知对象的状态是成功
//每个promise对象都成功
count++
//将当前promise对象成果的结果存入到数组
arr[i] = v
//判断
if (count === promises.length) {
//修改状态
resolve(arr)
}
}, r => {
reject(r)
})
}
})
}
//添加race方法
Promise.race = function (promises) {
return new Promise((resolve, reject) => {
if (promises.length === 0) return; // 永久pending
for (let i = 0; i < promises.length; i++) {
// 确保处理的是 Promise 对象
Promise.resolve(promises[i]).then(v => {
//修改返回对象的状态为[成功]
resolve(v)
}, r => {
//修改返回对象的状态为[失败]
reject(r)
})
}
})
}
//添加any方法
Promise.any = function (promises) {
return new Promise((resolve, reject) => {
// 用于收集所有错误
const errors = [];
// 记录已完成的 Promise 数量
let completed = 0;
// 空数组的特殊处理
if (promises.length === 0) {
reject(new AggregateError([], "No Promise passed"));
return;
}
// 遍历所有 Promise
for (let i = 0; i < promises.length; i++) {
// 确保处理的是 Promise 对象
Promise.resolve(promises[i]).then(
// 任何一个成功就立即 resolve
(value) => {
resolve(value);
},
// 失败时收集错误
(reason) => {
errors[i] = reason;
completed++;
// 当所有 Promise 都失败时 reject
if (completed === promises.length) {
reject(new AggregateError(errors, "All promises were rejected"));
}
}
);
}
})
};
// 添加 allSettled 方法
Promise.allSettled = function(promises) {
// 空数组特殊处理
if (promises.length === 0) {
return Promise.resolve([]);
}
return new Promise((resolve) => {
const results = new Array(promises.length);
let completed = 0;
// 使用 for 循环代替 forEach
for (let i = 0; i < promises.length; i++) {
// 确保处理的是 Promise 对象
Promise.resolve(promises[i])
.then(value => {
results[i] = { status: 'fulfilled', value };
})
.catch(reason => {
results[i] = { status: 'rejected', reason };
})
.finally(() => {
completed++;
// 检查是否所有 Promise 都已完成
if (completed === promises.length) {
resolve(results);
}
});
}
});
};
// 添加 withResolvers 方法
Promise.withResolvers = function() {
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
};